Wie übergebe ich eine durch Kommas getrennte Liste an eine gespeicherte Prozedur?

StackOverflow https://stackoverflow.com/questions/6369

  •  08-06-2019
  •  | 
  •  

Frage

Ich habe also eine in Sybase gespeicherte Prozedur, die einen Parameter annimmt, der eine durch Kommas getrennte Liste von Zeichenfolgen ist, und eine Abfrage mit in in einer IN()-Klausel ausführt:

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (@keyList)

Wie rufe ich meine gespeicherte Prozedur mit mehr als einem Wert in der Liste auf?Bisher habe ich es versucht

exec getSomething 'John'         -- works but only 1 value
exec getSomething 'John','Tom'   -- doesn't work - expects two variables
exec getSomething "'John','Tom'" -- doesn't work - doesn't find anything
exec getSomething '"John","Tom"' -- doesn't work - doesn't find anything
exec getSomething '\'John\',\'Tom\'' -- doesn't work - syntax error

BEARBEITEN: Das habe ich tatsächlich gefunden Seite Das enthält einen guten Hinweis auf die verschiedenen Möglichkeiten, ein Array an einen Sproc zu übergeben

War es hilfreich?

Lösung

Wenn Sie Sybase 12.5 oder früher verwenden, können Sie keine Funktionen verwenden.Eine Problemumgehung könnte darin bestehen, eine temporäre Tabelle mit den Werten zu füllen und sie von dort zu lesen.

Andere Tipps

Das ist etwas spät, aber genau dieses Problem hatte ich vor einiger Zeit und habe eine Lösung gefunden.

Der Trick besteht darin, doppelte Anführungszeichen zu setzen und dann die gesamte Zeichenfolge in Anführungszeichen zu setzen.

exec getSomething """John"",""Tom"",""Bob"",""Harry"""

Ändern Sie Ihren Prozess so, dass er den Tabelleneintrag mit der Zeichenfolge übereinstimmt.

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE @keyList LIKE '%'+name+'%' 

Ich habe dies seit ASE 12.5 in der Produktion;wir sind jetzt am 15.0.3.

Übergeben Sie die durch Kommas getrennte Liste an eine Funktion, die einen Tabellenwert zurückgibt.Irgendwo auf StackOverflow gibt es ein MS SQL-Beispiel, verdammt, wenn ich es im Moment sehen kann.

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (fn_GetKeyList(@keyList))

Rufen Sie an mit -

exec getSomething 'John,Tom,Foo,Bar'

Ich vermute, Sybase sollte in der Lage sein, etwas Ähnliches zu tun?

Müssen Sie eine durch Kommas getrennte Liste verwenden?In den letzten Jahren habe ich diese Art von Idee aufgegriffen und eine XML-Datei übergeben.Die „Funktion“ von openxml nimmt eine Zeichenfolge und macht sie wie XML. Wenn Sie dann eine temporäre Tabelle mit den Daten erstellen, ist diese abfragbar.

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
      <OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
      <OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
      <OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/ROOT/Customer',1)
            WITH (CustomerID  varchar(10),
                  ContactName varchar(20))

Bezüglich Kevins Idee, den Parameter an eine Funktion zu übergeben, die den Text in eine Tabelle aufteilt, ist hier meine Implementierung dieser Funktion von vor ein paar Jahren.Funktioniert ein Genuss.

Aufteilen von Text in Wörter in SQL

Dies ist eine schnelle und schmutzige Methode, die nützlich sein kann:

select  * 
from    mytbl 
where   "," + ltrim(rtrim(@keylist)) + "," like "%," + ltrim(rtrim(name)) + ",%"

Ich bin mir nicht sicher, ob es in ASE ist, aber in SQL Anywhere sa_split_list Die Funktion gibt eine Tabelle aus einer CSV zurück.Es verfügt über optionale Argumente zur Übergabe eines anderen Trennzeichens (Standard ist ein Komma) und einer maximalen Länge für jeden zurückgegebenen Wert.

sa_split_list-Funktion

Das Problem mit solchen Anrufen:exec getSomething '"John","Tom"' bedeutet, dass es "John", "Tom"" als einzelne Zeichenfolge behandelt und nur mit einem Eintrag in der Tabelle übereinstimmt, der ""John", "Tom"" ist.

Wenn Sie keine temporäre Tabelle wie in Pauls Antwort verwenden möchten, können Sie dynamisches SQL verwenden.(Setzt v12+ voraus)

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
declare @sql varchar(4096)
select @sql = "SELECT * FROM mytbl WHERE name IN (" + @keyList +")"
exec(@sql)

Sie müssen sicherstellen, dass die Elemente in @keylist in Anführungszeichen gesetzt sind, auch wenn es sich um Einzelwerte handelt.

Um auf die Bereitstellung von @Abel einzugehen: Was mir geholfen hat, war:

Mein Ziel war es, das von SSRs eingegebene Endbenutzer zu nehmen und diese in meiner Where -Klausel als in (ausgewählte) zu verwenden. Offensichtlich würde @ICD_Value_RPT in meiner Datensatzabfrage kommentiert.

DECLARE @ICD_VALUE_RPT VARCHAR(MAX) SET @ICD_VALUE_RPT = 'Value1, Value2'
DECLARE @ICD_VALUE_ARRAY XML SET @ICD_VALUE_ARRAY = CONCAT('<id>', REPLACE(REPLACE(@ICD_VALUE_RPT, ',', '</id>,<id>'),' ',''), '</id>')

dann in meinem WHERE Ich fügte hinzu:

(PATS_WITH_PL_DIAGS.ICD10_CODE IN (SELECT ParamValues.ID.value('.','VARCHAR(MAX)') FROM @ICD_VALUE_ARRAY.nodes('id') AS ParamValues(ID))
OR PATS_WITH_PL_DIAGS.ICD9_CODE IN (SELECT ParamValues.ID.value('.','VARCHAR(MAX)') FROM @ICD_VALUE_ARRAY.nodes('id') AS ParamValues(ID))
)

Versuchen Sie es auf diese Weise.Bei mir funktioniert es.

@itemIds varchar(max)

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (SELECT Value FROM [Global_Split] (@itemIds,','))

Dies funktioniert in SQL.Erklären Sie in Ihrem GetSomething Verfahren Sie eine Variable vom Typ XML als solche:

DECLARE @NameArray XML = NULL

Der Hauptteil der gespeicherten Prozedur implementiert Folgendes:

SELECT * FROM MyTbl WHERE name IN (SELECT ParamValues.ID.value('.','VARCHAR(10)')
FROM @NameArray.nodes('id') AS ParamValues(ID))

Aus dem SQL-Code, der den SP aufruft, um die XML-Variable zu deklarieren und zu initialisieren, bevor die gespeicherte Prozedur aufgerufen wird:

DECLARE @NameArray XML

SET @NameArray = '<id><</id>id>Name_1<<id>/id></id><id><</id>id>Name_2<<id>/id></id><id><</id>id>Name_3<<id>/id></id><id><</id>id>Name_4<<id>/id></id>'

In Ihrem Beispiel würde der Aufruf der gespeicherten Prozedur wie folgt aussehen:

EXEC GetSomething @NameArray

Ich habe diese Methode schon einmal verwendet und sie funktioniert gut.Wenn Sie einen schnellen Test wünschen, kopieren Sie den folgenden Code, fügen Sie ihn in eine neue Abfrage ein und führen Sie ihn aus:

DECLARE @IdArray XML

SET @IdArray = '<id><</id>id>Name_1<<id>/id></id><id><</id>id>Name_2<<id>/id></id><id><</id>id>Name_3<<id>/id></id><id><</id>id>Name_4<<id>/id></id>'

SELECT ParamValues.ID.value('.','VARCHAR(10)')
FROM @IdArray.nodes('id') AS ParamValues(ID)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top