Wie übergebe ich ein Array an eine gespeicherte SQL Server-Prozedur?
Zum Beispiel habe ich eine Liste von Mitarbeitern. Ich möchte diese Liste als Tabelle verwenden und sie mit einer anderen Tabelle verbinden. Die Liste der Mitarbeiter sollte jedoch als Parameter von C # übergeben werden.
c#
sql-server
tsql
stored-procedures
Sergey
quelle
quelle
Antworten:
SQL Server 2008 (oder neuer)
Erstellen Sie zunächst in Ihrer Datenbank die folgenden zwei Objekte:
Jetzt in Ihrem C # -Code:
SQL Server 2005
Wenn Sie SQL Server 2005 verwenden, würde ich weiterhin eine Split-Funktion über XML empfehlen. Erstellen Sie zunächst eine Funktion:
Jetzt kann Ihre gespeicherte Prozedur einfach sein:
Und in Ihrem C # -Code müssen Sie nur die Liste als
'1,2,3,12'
...Ich finde, dass die Methode zum Durchlaufen von Parametern mit Tabellenwerten die Wartbarkeit einer Lösung, die sie verwendet, vereinfacht und im Vergleich zu anderen Implementierungen, einschließlich XML und Aufteilen von Zeichenfolgen, häufig eine höhere Leistung aufweist.
Die Eingaben sind klar definiert (niemand muss raten, ob das Trennzeichen ein Komma oder ein Semikolon ist), und wir haben keine Abhängigkeiten von anderen Verarbeitungsfunktionen, die nicht offensichtlich sind, ohne den Code für die gespeicherte Prozedur zu überprüfen.
Im Vergleich zu Lösungen mit benutzerdefiniertem XML-Schema anstelle von UDTs umfasst dies eine ähnliche Anzahl von Schritten, aber meiner Erfahrung nach ist das Verwalten, Verwalten und Lesen von Code weitaus einfacher.
quelle
SELECT [colA] FROM [MyTable] WHERE [Id] IN (SELECT [Id] FROM @ListOfIds)
.Nach meiner Erfahrung gibt es eine knifflige und nette Lösung für dieses Problem, indem aus den Mitarbeiter-IDs ein abgegrenzter Ausdruck erstellt wird. Sie sollten nur einen Zeichenfolgenausdruck wie
';123;434;365;'
in-which erstellen123
,434
und365
einige employeeIDs. Wenn Sie die folgende Prozedur aufrufen und diesen Ausdruck an ihn übergeben, können Sie die gewünschten Datensätze abrufen. Sie können dieser Abfrage ganz einfach die "andere Tabelle" hinzufügen. Diese Lösung ist für alle Versionen von SQL Server geeignet. Im Vergleich zur Verwendung von Tabellenvariablen oder temporären Tabellen ist dies eine sehr schnelle und optimierte Lösung.quelle
Verwenden Sie einen tabellenwertigen Parameter für Ihre gespeicherte Prozedur.
Wenn Sie es von C # übergeben, fügen Sie den Parameter mit dem Datentyp SqlDb.Structured hinzu.
Siehe hier: http://msdn.microsoft.com/en-us/library/bb675163.aspx
Beispiel:
quelle
Sie müssen es als XML-Parameter übergeben.
Bearbeiten: Schnellcode aus meinem Projekt, um Ihnen eine Idee zu geben:
Dann können Sie die temporäre Tabelle verwenden, um sich mit Ihren Tabellen zu verbinden. Wir haben arrayOfUlong als integriertes XML-Schema definiert, um die Datenintegrität aufrechtzuerhalten, aber das müssen Sie nicht tun. Ich würde empfehlen, es zu verwenden. Hier ist ein kurzer Code, um sicherzustellen, dass Sie immer ein XML mit Longs erhalten.
quelle
Der Kontext ist immer wichtig, z. B. die Größe und Komplexität des Arrays. Für kleine bis mittelgroße Listen sind einige der hier veröffentlichten Antworten in Ordnung, obwohl einige Klarstellungen vorgenommen werden sollten:
text()
XML-Funktion. Weitere Informationen (z. B. Leistungsanalyse) zur Verwendung von XML zum Teilen von Listen finden Sie unter "Verwenden von XML zum Übergeben von Listen als Parameter in SQL Server" von Phil Factor.DataTable
bedeutet das Speichern aller Daten jedoch, dass die Daten im Speicher dupliziert werden, wenn sie aus der ursprünglichen Sammlung kopiert werden. DaherDataTable
funktioniert die Verwendung der Methode zur Übergabe von TVPs für größere Datenmengen nicht gut (dh sie lässt sich nicht gut skalieren).DataTable
TVP-Methode lässt sich XML nicht gut skalieren, da es die Datengröße im Speicher mehr als verdoppelt, da zusätzlich der Overhead des XML-Dokuments berücksichtigt werden muss.Wenn die von Ihnen verwendeten Daten groß sind oder noch nicht sehr groß sind, aber stetig wachsen, ist die
IEnumerable
TVP-Methode die beste Wahl, da sie die Daten an SQL Server überträgt (wie dieDataTable
Methode), ABER nicht erfordern eine Duplizierung der Sammlung im Speicher (im Gegensatz zu allen anderen Methoden). Ich habe in dieser Antwort ein Beispiel für den SQL- und C # -Code gepostet:Übergeben Sie das Wörterbuch an die gespeicherte Prozedur T-SQL
quelle
Es gibt keine Unterstützung für Arrays in SQL Server, aber es gibt verschiedene Möglichkeiten, wie Sie die Sammlung an einen gespeicherten Prozess übergeben können.
Der folgende Link kann Ihnen helfen
Übergabe der Sammlung an eine gespeicherte Prozedur
quelle
Ich habe alle Beispiele und Antworten durchsucht, wie ein Array an einen SQL Server übergeben werden kann, ohne dass ein neuer Tabellentyp erstellt werden muss, bis ich diesen Link gefunden habe. Im Folgenden habe ich ihn auf mein Projekt angewendet:
- Der folgende Code ruft ein Array als Parameter ab und fügt die Werte dieses Arrays in eine andere Tabelle ein
Hoffe es gefällt euch
quelle
@s
CSV ist, ist es schneller, dies einfach zu teilen (dh INSERT IN ... SELECT FROM SplitFunction). Die Konvertierung in XML ist langsamer als CLR, und attributbasiertes XML ist ohnehin viel schneller. Und dies ist eine einfache Liste, aber die Übergabe von XML oder TVP kann auch komplexe Arrays verarbeiten. Ich bin mir nicht sicher, was durch das Vermeiden eines einfachen, einmaligen Ereignisses erreicht wirdCREATE TYPE ... AS TABLE
.Das wird dir helfen. :) Befolgen Sie die nächsten Schritte,
Kopieren Fügen Sie den folgenden Code so ein, wie er ist. Dadurch wird die Funktion erstellt, die den String in Int konvertiert
Erstellen Sie die folgende gespeicherte Prozedur
Führen Sie diesen SP aus.
exec sp_DeleteId '1,2,3,12'
Dies ist eine Zeichenfolge von IDs, die Sie löschen möchten.Sie konvertieren Ihr Array in C # in einen String und übergeben es als Parameter für die gespeicherte Prozedur
Dadurch werden mehrere Zeilen gelöscht. Alles Gute
quelle
Ich habe lange gebraucht, um das herauszufinden, falls jemand es braucht ...
Dies basiert auf der SQL 2005-Methode in Aarons Antwort und verwendet seine SplitInts-Funktion (ich habe gerade den Delim-Parameter entfernt, da ich immer Kommas verwenden werde). Ich verwende SQL 2008, wollte aber etwas, das mit typisierten Datasets (XSD, TableAdapters) funktioniert, und ich weiß, dass String-Parameter mit diesen funktionieren.
Ich habe versucht, seine Funktion dazu zu bringen, in einer Klausel vom Typ "where in (1,2,3)" zu arbeiten, und hatte auf einfache Weise kein Glück. Also habe ich zuerst eine temporäre Tabelle erstellt und dann einen inneren Join anstelle des "where in" durchgeführt. Hier ist mein Beispiel: In meinem Fall wollte ich eine Liste von Rezepten erhalten, die bestimmte Zutaten nicht enthalten:
quelle
Wie bereits erwähnt, besteht eine Möglichkeit darin, das Array in eine Zeichenfolge zu konvertieren und die Zeichenfolge dann in SQL Server aufzuteilen.
Ab SQL Server 2016 gibt es eine integrierte Möglichkeit, aufgerufene Zeichenfolgen aufzuteilen
Es gibt eine Reihe von Zeilen zurück, die Sie in Ihre temporäre Tabelle (oder echte Tabelle) einfügen können.
ergäbe:
Wenn Sie schicker werden möchten:
würde Ihnen die gleichen Ergebnisse wie oben geben (außer dass der Spaltenname "thenumber" ist), aber sortiert. Sie können die Tabellenvariable wie jede andere Tabelle verwenden, sodass Sie sie bei Bedarf problemlos mit anderen Tabellen in der Datenbank verknüpfen können.
Beachten Sie, dass Ihre SQL Server-Installation auf Kompatibilitätsstufe 130 oder höher sein muss, damit die
STRING_SPLIT()
Funktion erkannt wird. Sie können Ihre Kompatibilitätsstufe mit der folgenden Abfrage überprüfen:Die meisten Sprachen (einschließlich C #) verfügen über eine "Join" -Funktion, mit der Sie eine Zeichenfolge aus einem Array erstellen können.
Dann übergeben Sie
sqlparam
als Parameter die oben gespeicherte Prozedur.quelle
quelle