5 Stimmen

Dynamische SQL-Abfrage mit kommagetrennten Werten

[Aktualisierung: Verwendung von SQL Server 2005]

Hallo, was ich tun möchte, ist meine gespeicherte Prozedur mit einer Komma-getrennten Liste von Werten (ids) abfragen, um Zeilen von Daten abzurufen.

Das Problem, das ich erhalte, ist ein Konvertierungsfehler:

Conversion failed when converting the varchar value ' +
@PassedInIDs + ' to data type int.

Die Aussage in meinem where-Klausel und Fehler ist:

...
AND (database.ID IN (' + @PassedInIDs + '))

Hinweis: Datenbank.ID ist vom Typ int.

Ich habe den Artikel auf verfolgt:

http://www.sql-server-helper.com/functions/comma-delimited-to-table.aspx

wurde aber aufgrund des Fehlers nicht abgeschlossen.

In meinem Ausführungsskript habe ich:

...
@PassedInIDs= '1,5'

Mache ich hier etwas falsch? Ich danke Ihnen für Ihre Hilfe.

1voto

Tom H Punkte 45699

Ich würde Ihnen dringend empfehlen, die zweite Methode aus diesem Link zu verwenden. Erstellen Sie eine benutzerdefinierte Funktion, die Ihre durch Kommata getrennte Zeichenfolge in eine Tabelle umwandelt, aus der Sie dann problemlos auswählen können.

Wenn Sie eine Google auf Erland und "Dynamic SQL" hat er eine gute writeup der Fallstricke, die es mit sich bringt.

1voto

hova Punkte 2731

Zum einen übergeben Sie eine Zeichenkette an die IN-Funktion in SQL. Wenn Sie sich den ursprünglichen Artikel noch einmal ansehen, werden Sie feststellen, dass anstelle einer direkten SQL-Anweisung eine string die die auszuführende SQL-Anweisung ist.

1voto

Tomalak Punkte 320467

In SQL gibt es keine String-Auswertung. Dies:

database.ID IN (' + @PassedInIDs + ')

wird nicht angegangen werden:

database.ID IN (1,2,3)

nur weil die @PassedInIDs Parameter enthält zufällig '1,2,3' . Der Parameter wird nicht einmal betrachtet, denn Sie haben nur eine String mit " + @PassedInIDs + " . Syntaktisch ist dies gleichbedeutend mit:

database.ID IN ('Bob')

Um es kurz zu machen: Was Sie hier versuchen, können Sie in SQL nicht tun. Aber es gibt vier andere Möglichkeiten:

  1. Sie konstruieren den SQL-String in der aufrufenden Sprache und lassen die gespeicherte Prozedur ganz weg.
  2. Sie verwenden eine dynamische vorbereitete Anweisung mit so vielen Parametern in der IN-Klausel, wie Sie verwenden möchten
  3. Sie verwenden eine fest vorbereitete Anweisung mit z.B. 10 Parametern: IN (?,?,?,?,?,?,?,?,?,?) nur so viele, wie Sie benötigen, und setzen Sie die anderen auf NULL
  4. Sie erstellen eine gespeicherte Prozedur mit z.B. 10 Parametern und geben so viele wie nötig ein, wobei die anderen auf NULL gesetzt werden: IN (@p1, @p2, ..., @p10) .

1voto

casperOne Punkte 72238

Ich würde eine CLR-Funktion mit Tabellenwert erstellen:

http://msdn.microsoft.com/en-us/library/ms131103.aspx

Darin würden Sie die Zeichenfolge zerlegen und eine Konvertierung in eine Reihe von Zeilen vornehmen. Sie können dann eine Verknüpfung mit den Ergebnissen dieser Tabelle herstellen oder IN verwenden, um festzustellen, ob eine ID in der Liste enthalten ist.

0voto

david.mchonechase Punkte 2149

Sie müssen ufn_CSVToTable so behandeln, als wäre es eine Tabelle. So können Sie die Funktion verbinden:

JOIN ufn_CSVToTable(@PassedInIDs) uf ON database.ID = uf.[String]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X