Comment passer un tableau dans une procédure stockée SQL Server?
Par exemple, j'ai une liste d'employés. Je veux utiliser cette liste comme table et la joindre à une autre table. Mais la liste des employés doit être passée en paramètre à partir de C #.
c#
sql-server
tsql
stored-procedures
Sergey
la source
la source
Réponses:
SQL Server 2008 (ou plus récent)
Tout d'abord, dans votre base de données, créez les deux objets suivants:
Maintenant dans votre code C #:
SQL Server 2005
Si vous utilisez SQL Server 2005, je recommanderais toujours une fonction partagée sur XML. Créez d'abord une fonction:
Maintenant, votre procédure stockée peut simplement être:
Et dans votre code C #, il vous suffit de passer la liste en tant que
'1,2,3,12'
...Je trouve que la méthode de passage à travers les paramètres de valeur de table simplifie la maintenabilité d'une solution qui l'utilise et a souvent des performances accrues par rapport à d'autres implémentations, y compris XML et le fractionnement de chaînes.
Les entrées sont clairement définies (personne n'a à deviner si le délimiteur est une virgule ou un point-virgule) et nous n'avons pas de dépendances sur d'autres fonctions de traitement qui ne sont pas évidentes sans inspecter le code de la procédure stockée.
Comparé aux solutions impliquant un schéma XML défini par l'utilisateur au lieu d'UDT, cela implique un nombre similaire d'étapes, mais d'après mon expérience, il est beaucoup plus simple de gérer, de maintenir et de lire du code.
la source
SELECT [colA] FROM [MyTable] WHERE [Id] IN (SELECT [Id] FROM @ListOfIds)
.D'après mon expérience, en créant une expression délimitée à partir des ID d'employé, il existe une solution délicate et agréable à ce problème. Vous ne devez créer qu'une expression de chaîne comme
';123;434;365;'
in-which123
,434
et il365
s'agit de certains ID d'employé. En appelant la procédure ci-dessous et en lui passant cette expression, vous pouvez récupérer les enregistrements souhaités. Vous pouvez facilement joindre la "autre table" à cette requête. Cette solution convient à toutes les versions de SQL Server. En outre, en comparaison avec l'utilisation d'une table variable ou d'une table temporaire, c'est une solution très rapide et optimisée.la source
Utilisez un paramètre table pour votre procédure stockée.
Lorsque vous le transmettez à partir de C #, vous ajoutez le paramètre avec le type de données SqlDb.Structured.
Voir ici: http://msdn.microsoft.com/en-us/library/bb675163.aspx
Exemple:
la source
Vous devez le passer en tant que paramètre XML.
Edit: code rapide de mon projet pour vous donner une idée:
Ensuite, vous pouvez utiliser la table temporaire pour rejoindre vos tables. Nous avons défini arrayOfUlong comme un schéma XML intégré pour maintenir l'intégrité des données, mais vous n'avez pas à le faire. Je recommanderais de l'utiliser alors voici un code rapide pour vous assurer d'obtenir toujours un XML avec longs.
la source
Le contexte est toujours important, comme la taille et la complexité du tableau. Pour les petites et moyennes listes, plusieurs des réponses publiées ici sont très bien, bien que certaines clarifications doivent être apportées:
text()
Fonction XML. Pour plus d'informations (analyse des performances, par exemple) sur l'utilisation de XML pour fractionner des listes, consultez «Utilisation de XML pour transmettre des listes en tant que paramètres dans SQL Server» par Phil Factor.DataTable
signifie la duplication des données en mémoire lors de leur copie à partir de la collection d'origine. Par conséquent, l'utilisation de laDataTable
méthode de transmission des TVP ne fonctionne pas bien pour de plus grands ensembles de données (c'est-à-dire qu'elle ne s'adapte pas bien).DataTable
méthode TVP, XML n'évolue pas bien car il fait plus que doubler la taille des données en mémoire car il doit en outre prendre en compte les frais généraux du document XML.Cela dit, SI les données que vous utilisez sont grandes ou pas encore très grandes mais en croissance constante, la
IEnumerable
méthode TVP est le meilleur choix car elle diffuse les données vers SQL Server (comme laDataTable
méthode), MAIS ne le fait pas exiger toute duplication de la collection en mémoire (contrairement à toutes les autres méthodes). J'ai posté un exemple de code SQL et C # dans cette réponse:Passer le dictionnaire à la procédure stockée T-SQL
la source
Il n'y a pas de prise en charge du tableau dans le serveur SQL mais il existe plusieurs façons de transmettre la collection à un proc stocké.
Le lien ci-dessous peut vous aider
passage d'une collection à une procédure stockée
la source
J'ai cherché à travers tous les exemples et les réponses sur la façon de passer n'importe quel tableau au serveur SQL sans avoir à créer de nouveau type de table, jusqu'à ce que je trouve ce linK , voici comment je l'ai appliqué à mon projet:
--Le code suivant va obtenir un tableau en tant que paramètre et insérer les valeurs de ce - tableau dans une autre table
Je espère que vous l'apprécierez
la source
@s
est CSV, il serait plus rapide de simplement le diviser (c.-à-d. INSÉRER DANS ... SÉLECTIONNER À PARTIR DE SplitFunction). La conversion en XML est plus lente que CLR, et le XML basé sur les attributs est de toute façon beaucoup plus rapide. Et ceci est une liste simple mais en passant en XML ou TVP peut également gérer des tableaux complexes. Je ne sais pas ce qui est gagné en évitant un simple, ponctuelCREATE TYPE ... AS TABLE
.Cela vous aidera. :) Suivez les étapes suivantes,
Copiez Collez le code suivant tel qu'il est, cela créera la fonction qui convertira la chaîne en Int
Créer la procédure stockée suivante
Exécutez ce SP.
exec sp_DeleteId '1,2,3,12'
Il s'agit d'une chaîne d'ID que vous souhaitez supprimer,Vous convertissez votre tableau en chaîne en C # et le transmettez en tant que paramètre de procédure stockée
Cela supprimera plusieurs lignes, tout le meilleur
la source
Il m'a fallu beaucoup de temps pour comprendre cela, donc au cas où quelqu'un en aurait besoin ...
Ceci est basé sur la méthode SQL 2005 dans la réponse d'Aaron, et en utilisant sa fonction SplitInts (je viens de supprimer le paramètre delim car je vais toujours utiliser des virgules). J'utilise SQL 2008 mais je voulais quelque chose qui fonctionne avec des ensembles de données typés (XSD, TableAdapters) et je sais que les paramètres de chaîne fonctionnent avec ceux-ci.
J'essayais de faire fonctionner sa fonction dans une clause de type "where in (1,2,3)", et je n'avais aucune chance de manière directe. J'ai donc d'abord créé une table temporaire, puis j'ai fait une jointure interne au lieu de "where in". Voici mon exemple d'utilisation, dans mon cas, je voulais obtenir une liste de recettes qui ne contiennent pas certains ingrédients:
la source
Comme d'autres l'ont noté ci-dessus, une façon de procéder consiste à convertir votre tableau en chaîne, puis à diviser la chaîne dans SQL Server.
Depuis SQL Server 2016, il existe un moyen intégré de fractionner les chaînes appelé
Il renvoie un ensemble de lignes que vous pouvez insérer dans votre table temporaire (ou table réelle).
donnerait:
Si vous voulez devenir plus amateur:
vous donnerait les mêmes résultats que ci-dessus (sauf que le nom de la colonne est "numéro"), mais trié. Vous pouvez utiliser la variable de table comme n'importe quelle autre table, vous pouvez donc facilement la joindre à d'autres tables de la base de données si vous le souhaitez.
Notez que votre installation SQL Server doit être au niveau de compatibilité 130 ou supérieur pour que la
STRING_SPLIT()
fonction soit reconnue. Vous pouvez vérifier votre niveau de compatibilité avec la requête suivante:La plupart des langages (y compris C #) ont une fonction "join" que vous pouvez utiliser pour créer une chaîne à partir d'un tableau.
Ensuite, vous passez
sqlparam
comme paramètre à la procédure stockée ci-dessus.la source
la source