Cum să treci o listă separată prin virgulă la o procedură stocată?

Deci, am un proc stocat Sybase care ia un parametru care este o listă de șiruri separate prin virgule și rulează o interogare cu intr-o clauză IN ():

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

Cum îmi sun eu protocolul stocat cu mai mult de o valoare în listă? Până acum am încercat

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

EDIT: I actually found this page that has a great reference of the various ways to pas an array to a sproc

0
fr hi bn
adăugat autor icc97, sursa
Sper că ați găsit o metodă care a funcționat pentru dvs. Pagina legată este o listă bună de opțiuni, dar mă bucur să văd că majoritatea au fost sugerate deja aici! Pavel a sugerat metoda 2/3, tabele temp. Am sugerat metoda 1, sql dinamic. Brian și Abel sugerează o metodă XML, deși nu sunt licențiată pentru xml în sybase, așa că nu știu dacă aceasta va funcționa în Sybase. Similar cu metoda 4.
adăugat autor AdamH, sursa

10 răspunsuri

În ceea ce privește ideea lui Kevin de a transmite parametrul unei funcții care împarte textul într-un tabel, iată implementarea acestei funcții de la câțiva ani în urmă. Lucrează un tratament.

Împărțirea textului în cuvinte în SQL

0
adăugat

Trebuie să utilizați o listă separată prin virgulă? În ultimii ani, am luat acest tip de idee și am trecut într-un fișier XML. Funcția openxml "are" un șir și o face ca xml și apoi dacă creezi un tabel temp cu datele, este interogabil.

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='


   
      
      
   


   
      
   

'
--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))
0
adăugat

Treceți lista separată prin virgulă într-o funcție care returnează o valoare tabelă. Există un exemplu MS SQL undeva pe StackOverflow, blestemat dacă îl pot vedea în acest moment.

  CREAȚI PROCEDURA getSomething @keyList varchar (4096)
LA FEL DE
SELECT * FROM mytbl WHERE nume IN (fn_GetKeyList (@keyList))
 

Apelați cu -

  exec getSomething "John, Tom, Foo, Bar"
 

Cred că Sybase ar trebui să poată face ceva similar?

0
adăugat

Încearcă în felul ăsta. Lucrările mele pentru mine.

@itemIds varchar(max)

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

Problema cu apelurile de genul: exec getSomething "John", "Tom" este că se tratează "John", "Tom" "ca un singur șir, se va potrivi doar o intrare în tabel care este" Ioan“, "Tom"“.

Dacă nu ați vrea să utilizați o masă temporală ca în răspunsul lui Pavel, atunci ați putea folosi dinamic sql. (Presupune v12 +)

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

Va trebui să vă asigurați că elementele din @keylist au citate în jurul lor, chiar dacă acestea sunt valori unice.

0
adăugat

Dacă utilizați Sybase 12.5 sau o versiune anterioară, atunci nu puteți utiliza funcții. O soluție ar putea fi să populezi o masă temporară cu valorile și să le citești de acolo.

0
adăugat

Nu este sigur dacă este în ASE, dar în SQL Anywhere, funcția sa_split_list returnează o tabelă dintr-un CSV. Are argumente opționale pentru a trece un alt delimiter (implicit este o virgulă) și o lungime maximă pentru fiecare valoare returnată.

Funcția sa_split_list

0
adăugat

Aceasta funcționează în SQL. Declarați în procedura GetSomething o variabilă de tip xml ca atare:

DECLARE @NameArray xml = NULL

Corpul procedurii memorate implementează următoarele:

SELECT * FROM MyTbl WHERE nume în (SELECT ParamValues.ID.value ('.', 'VARCHAR (10)')   Din @ NumeArray.nodes ('id') AS ParamValues ​​(ID))

Din cadrul codului SQL care solicită SP să declare și să inițializeze variabila xml înainte de a apela procedura stocată:

DECLARE @NameArray xml

     

SET @NameArray = ' Nume_1 Nume_2

Folosind exemplul dvs., apelul la procedura stocată ar fi:

EXEC GetSomething @NameArray

Am folosit această metodă înainte și funcționează bine. Dacă doriți un test rapid, copiați și inserați următorul cod într-o interogare nouă și executați:

DECLARE @IdArray xml

     

SET @IdArray = ' Nume_1 Nume_2      

SELECT ParamValues.ID.value ('.', 'VARCHAR (10)')   DE LA @ IdArray.nodes ('id') AS ParamValues ​​(ID)

0
adăugat

Acest lucru este cam târziu, dar am avut această problemă exactă cu ceva timp în urmă și am găsit o soluție.

Trucul este citarea dublă și apoi împachetarea întregului șir în citate.

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

Modificați procesul de proc pentru a se potrivi cu intrarea tabelului în șir.

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

Am avut acest lucru în producție de la ASE 12.5; acum suntem pe 15.0.3.

0
adăugat
S-ar putea să doriți să căutați în acest ... Dacă aveți Jack în masă și căutați Jackie veți obține de fapt Jack :) De asemenea, probabil că nu e teribil de eficient, creând un șir pentru fiecare rând din tabel.
adăugat autor JanHudecek, sursa

Pentru a atinge ceea ce a oferit @Abel, ceea ce ma ajutat a fost:

Scopul meu a fost să iau ceea ce utilizatorul final a introdus din SSRS și să folosească acest lucru în clauza mea în cazul în care ca un In (SELECT) Evident, @ICD_VALUE_RPT ar fi comentat în interogarea mea Dataset.

DECLARE @ICD_VALUE_RPT VARCHAR(MAX) SET @ICD_VALUE_RPT = 'Value1, Value2'
DECLARE @ICD_VALUE_ARRAY xml SET @ICD_VALUE_ARRAY = CONCAT('', REPLACE(REPLACE(@ICD_VALUE_RPT, ',', ','),' ',''), '')

apoi în WHERE i-am adăugat:

(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))
)
0
adăugat