15

This page from SQL Server 2008 BOL, habla sobre los procedimientos almacenados de CLR y tiene una sección etiquetada, "Parámetros con valores de tabla", que explica cómo pueden ser ventajosos. Eso es genial. Me encantaría usar TVP en mis procesos CLR, pero desafortunadamente esta parece ser la única referencia en el universo a tal posibilidad, y la sección no describe cuál sería la sintaxis (ni tampoco la información adicional vinculado al final del párrafo)Parámetros con valores de tabla para procedimientos CLR en SQL Server 2008 - ¿es posible?

Claro, puedo encontrar fácilmente descripciones de cómo usar los TVP de los procesos T-SQL, o cómo hacer los procesos CLR en general. ¿Pero escribir un proceso CLR que tome un TVP? Nada. Todo esto es altamente inusual ya que el paso de datos de múltiples filas a un proceso almacenado es un problema popular.

Esto me lleva a preguntarme si la presencia de la sección en esa página es un error. Alguien por favor dígame que no es así y señale más información/ejemplos.

[EDIT]

que estaba a punto de publicar esto en uno de los foros MS demasiado cuando me encontré con this, which seems to be the final nail in the coffin. Parece que no se puede hacer.

Respuesta

5

Puedo encontrar un lotmorereferences. Sin embargo, todos estos son para pasar parámetros con valores de tabla a los procedimientos de TSQL, por lo que es de poca utilidad.

Sin embargo, he llegado a la conclusión de que es imposible. En primer lugar, está el list of mappings entre los tipos CLR y SQL. Para los tipos de tabla no hay ninguna asignación, por lo que el siguiente no funciona, por ejemplo:

[SqlProcedure] 
public static void StoredProcedure(DataTable tvp, out int sum) 
{ 
    return 42; 
} 

y luego

CREATE TYPE MyTableType AS TABLE 
(
    Id INT NOT NULL PRIMARY KEY, 
    [Count] INT NOT NULL 
) 
GO 
CREATE ASSEMBLY ClrTest FROM '<somePath>' 
GO 
CREATE PROCEDURE ClrTest 
AS EXTERNAL NAME ClrTest.StoredProcedures.StoredProcedure 
GO 

Cualquiera que sea el tipo intenta (DataTable, DbDataReader, IEnumerable), la llamada CREATE PROCEDURE mantiene generar un error 6552: CREAR PROCEDIMIENTO para "ClrTest" error porque los tipos T-SQL y CLR para el parámetro "@tvp" no coinciden.

En segundo lugar, la documentación en la página se ha vinculado a dice: un tipo de tabla definida por el usuario no se puede pasar como un parámetro con valores de tabla a, o ser devuelto a un procedimiento almacenado administrado o la función se ejecuta en el SQL Proceso del servidor.

Parece que no encuentro en ninguna parte cómo crear un tipo de tabla definido por el usuario en C#, pero esto también parece ser un callejón sin salida.

Tal vez pueda hacer su pregunta en algún lugar de un foro de Microsoft. Todavía es extraño que mencionen parámetros con valores de tabla en la página de sproc de CLR, pero nunca explican cómo implementar esto. Si encuentras alguna solución, me gustaría saber.

+0

Acabo de leer toda su pregunta en detalle. Props CLR, no TSQL. Perdón por esta respuesta en ese caso, intentaré encontrar una mejor solución ... –

+0

lol, np - gracias. Voy a mantener mi voto hasta que regrese, entonces ;-) – philsquared

+0

Gracias rw. Parece probable que ese párrafo en los documentos (que se agregó bastante recientemente) sea incorrecto. Seguiré en algún momento en uno de los foros de MS. – philsquared

1

Mientras que parece que pasa tablas directamente a procedimientos CLR es imposible en la actualidad, tengo un resultado, aunque sub óptima por:

  • definir una tabla de TSQL valorada UDT FooTable
  • definir una función TSQL que toma FooTable como un parámetro y devuelve XML mediante FOR XML EXPLICIT
  • pasando el XML resultante para la función CLR/procedimiento en lugar de la propia tabla
No

Identificación eal, pero se acerca un poco.

2

La solución es serializar sus datos tabulares en una cadena con formato Json y luego pasar la cadena en su proceso CLR. Dentro de su programa o función clr usted analizaría el json en un objeto IEnumerable, list u tabular. A continuación, puede trabajar con los datos como lo haría con cualquier otro tipo de datos tabulares.

He escrito algunas utilidades capaces de serializar cualquier tabla sql en una cadena con formato Json. Me complace compartirlos con cualquier persona que proporcione su dirección de correo electrónico. Phil Factor ha escrito un buen analizador Tson SQL Json al que llamó parseJson. He adaptado su solución al clr que funciona mucho más rápido. Ambos aceptan una cadena con formato Json y producen una tabla a partir de la cadena. También tengo una variedad de utilidades Json que empleo tanto con T-SQL como con CLR, que pueden serializar, analizar, insertar, borrar y actualizar cadenas formateadas Json almacenadas en columnas sql.

3

Puede usar una tabla temporal creada y rellenada antes de llamar al procedimiento y leer la tabla dentro del procedimiento clr.

+0

¿Qué se agrega a la respuesta actualmente aceptada? Esto debería ser un comentario, no una respuesta. Verifique esta [pregunta de metaSO] (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) y [Jon Skeet: Coding Blog] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) sobre cómo dar una respuesta correcta. – Yaroslav

+1

Esta respuesta es excelente, ya que toca un medio completamente diferente de pasar datos entre procedimientos almacenados que los mencionados en las otras respuestas. Consulte la publicación de blog clásica y definitiva de Erland Sommerskog en http://www.sommarskog.se/share_data.html#temptables sobre los pros y los contras de cada método en particular, donde analiza los casos de uso específicos para cada uno.La solución de tabla temporal tiene sus propios casos de uso únicos; Resultó ser la solución al problema que estaba buscando resolver cuando encontré este hilo. – SQLServerSteve

1

Si utiliza C# (a diferencia de VB, que carece de iteradores personalizados) se puede escribir código ADO.NET para invocar ExecuteNonQuery() y ejecuta un procedimiento almacenado con un SqlDbType.Structured parámetro (es decir, una TVP).

La recopilación aprobada como el valor de TVP debe implementar IEnumerable<SqlDataRecord>. Cada vez que regreso rendimiento de este IEnumerable se ejecuta, un SqlDataRecord “fila” está canalizada al parámetro "mesa".

Ver this article para más detalles.

Cuestiones relacionadas