¿Cómo pasar una matriz a un procedimiento almacenado de SQL Server?
Por ejemplo, tengo una lista de empleados. Quiero usar esta lista como una tabla y unirla con otra tabla. Pero la lista de empleados debe pasarse como parámetro desde C #.
c#
sql-server
tsql
stored-procedures
Sergey
fuente
fuente
Respuestas:
SQL Server 2008 (o más reciente)
Primero, en su base de datos, cree los siguientes dos objetos:
Ahora en su código C #:
SQL Server 2005
Si está utilizando SQL Server 2005, todavía recomendaría una función dividida sobre XML. Primero, crea una función:
Ahora su procedimiento almacenado puede ser:
Y en su código C # solo tiene que pasar la lista como
'1,2,3,12'
...Encuentro que el método de pasar a través de parámetros con valores de tabla simplifica el mantenimiento de una solución que lo utiliza y, a menudo, ha aumentado el rendimiento en comparación con otras implementaciones, incluidas la división de cadenas y XML.
Las entradas están claramente definidas (nadie tiene que adivinar si el delimitador es una coma o un punto y coma) y no tenemos dependencias de otras funciones de procesamiento que no sean obvias sin inspeccionar el código del procedimiento almacenado.
En comparación con las soluciones que implican un esquema XML definido por el usuario en lugar de UDT, esto implica un número similar de pasos, pero en mi experiencia es un código mucho más simple de administrar, mantener y leer.
fuente
SELECT [colA] FROM [MyTable] WHERE [Id] IN (SELECT [Id] FROM @ListOfIds)
.Según mi experiencia, al crear una expresión delimitada a partir de los Id. De empleado, hay una solución difícil y agradable para este problema. Sólo se debe crear una expresión de cadena como
';123;434;365;'
en los cuales123
,434
y365
algunas employeeIDs. Al llamar al siguiente procedimiento y pasarle esta expresión, puede obtener los registros que desee. Fácilmente puede unir la "otra tabla" en esta consulta. Esta solución es adecuada en todas las versiones del servidor SQL. Además, en comparación con el uso de tabla variable o tabla temporal, es una solución muy rápida y optimizada.fuente
Use un parámetro con valores de tabla para su procedimiento almacenado.
Cuando lo pase desde C #, agregará el parámetro con el tipo de datos de SqlDb.Structured.
Ver aquí: http://msdn.microsoft.com/en-us/library/bb675163.aspx
Ejemplo:
fuente
Debe pasarlo como un parámetro XML.
Editar: código rápido de mi proyecto para darle una idea:
Luego puede usar la tabla temporal para unirse a sus tablas. Definimos arrayOfUlong como un esquema XML incorporado para mantener la integridad de los datos, pero no tiene que hacerlo. Recomiendo usarlo, así que aquí hay un código rápido para asegurarse de que siempre obtenga un XML con longs.
fuente
El contexto siempre es importante, como el tamaño y la complejidad de la matriz. Para listas pequeñas a medianas, varias de las respuestas publicadas aquí están bien, aunque se deben hacer algunas aclaraciones:
text()
Función XML: para obtener más información (es decir, análisis de rendimiento) sobre el uso de XML para dividir listas, consulte "Uso de XML para pasar listas como parámetros en SQL Server" de Phil Factor.DataTable
significa duplicar los datos en la memoria a medida que se copian de la colección original. Por lo tanto, el uso delDataTable
método de pasar TVP no funciona bien para conjuntos de datos más grandes (es decir, no escala bien).DataTable
método TVP, XML no se escala bien, ya que duplica el tamaño de datos en la memoria, ya que también debe tener en cuenta la sobrecarga del documento XML.Dicho todo esto, SI los datos que está utilizando son grandes o aún no son muy grandes pero están creciendo constantemente, entonces el
IEnumerable
método TVP es la mejor opción ya que transmite los datos a SQL Server (como elDataTable
método), PERO no requieren cualquier duplicación de la colección en la memoria (a diferencia de cualquiera de los otros métodos). Publiqué un ejemplo del código SQL y C # en esta respuesta:Pasar diccionario al procedimiento almacenado T-SQL
fuente
No hay soporte para la matriz en el servidor sql, pero hay varias formas en que puede pasar la colección a un proceso almacenado.
El siguiente enlace puede ayudarlo
pasar la colección a un procedimiento almacenado
fuente
He estado buscando a través de todos los ejemplos y respuestas sobre cómo pasar cualquier matriz al servidor sql sin la molestia de crear un nuevo tipo de tabla, hasta que encontré este enlace , a continuación es cómo lo apliqué a mi proyecto:
El siguiente código obtendrá una matriz como parámetro e insertará los valores de esa matriz en otra tabla
Espero que lo disfrutes
fuente
@s
es CSV, entonces sería más rápido simplemente dividir eso (es decir, INSERTAR EN ... SELECCIONAR DESDE SplitFunction). La conversión a XML es más lenta que CLR, y el XML basado en atributos es mucho más rápido de todos modos. Y esta es una lista simple pero pasar XML o TVP también puede manejar arreglos complejos. No estoy seguro de lo que se gana evitando un simple, una vezCREATE TYPE ... AS TABLE
.Esto te ayudara. :) Sigue los siguientes pasos,
Copiar Pegar el siguiente código tal como está, creará la Función que convierte la Cadena a Int
Cree el siguiente procedimiento almacenado
Ejecute este SP. Usando
exec sp_DeleteId '1,2,3,12'
esto hay una cadena de Id que desea eliminar,Convierte su matriz en una cadena en C # y la pasa como un parámetro de Procedimiento almacenado
Esto eliminará varias filas, todo lo mejor
fuente
Me tomó mucho tiempo resolver esto, así que en caso de que alguien lo necesite ...
Esto se basa en el método SQL 2005 en la respuesta de Aaron, y usando su función SplitInts (acabo de eliminar el parámetro delim ya que siempre usaré comas). Estoy usando SQL 2008 pero quería algo que funcione con conjuntos de datos escritos (XSD, TableAdapters) y sé que los parámetros de cadena funcionan con ellos.
Estaba tratando de hacer que su función funcionara en una cláusula de tipo "dónde en (1,2,3)", y no tuve suerte en el camino directo. Así que creé una tabla temporal primero, y luego hice una unión interna en lugar del "en dónde". Aquí está mi ejemplo de uso, en mi caso quería obtener una lista de recetas que no contienen ciertos ingredientes:
fuente
Como otros han señalado anteriormente, una forma de hacerlo es convertir su matriz en una cadena y luego dividirla dentro de SQL Server.
A partir de SQL Server 2016, hay una forma integrada de dividir cadenas llamada
Devuelve un conjunto de filas que puede insertar en su tabla temporal (o tabla real).
produciría:
Si quieres ponerte más elegante:
le daría los mismos resultados que anteriormente (excepto que el nombre de la columna es "thenumber"), pero ordenado. Puede usar la variable de tabla como cualquier otra tabla, por lo que puede unirla fácilmente con otras tablas en la base de datos si lo desea.
Tenga en cuenta que su instalación de SQL Server debe estar en el nivel de compatibilidad 130 o superior para
STRING_SPLIT()
que se reconozca la función. Puede verificar su nivel de compatibilidad con la siguiente consulta:La mayoría de los lenguajes (incluido C #) tienen una función de "unión" que puede usar para crear una cadena a partir de una matriz.
Luego pasa
sqlparam
como parámetro al procedimiento almacenado anterior.fuente
fuente