Domanda

Quindi ho un processo memorizzato su Sybase che accetta 1 parametro che è un elenco di stringhe separate da virgole ed esegue una query con in in una clausola IN():

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

Come posso chiamare il mio proc memorizzato con più di 1 valore nell'elenco?Finora ho provato

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

MODIFICARE: In realtà ho trovato questo pagina che ha un ottimo riferimento ai vari modi per passare un array a uno sproc

È stato utile?

Soluzione

Se utilizzi Sybase 12.5 o versioni precedenti non puoi utilizzare le funzioni.Una soluzione alternativa potrebbe essere quella di popolare una tabella temporanea con i valori e leggerli da lì.

Altri suggerimenti

È un po' tardi, ma ho avuto lo stesso problema qualche tempo fa e ho trovato una soluzione.

Il trucco sta nel mettere le virgolette doppie e poi racchiudere l'intera stringa tra virgolette.

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

Modifica il tuo proc per abbinare la voce della tabella alla stringa.

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

L'ho in produzione da ASE 12.5;ora siamo al 15.0.3.

Passa l'elenco separato da virgole in una funzione che restituisce un valore di tabella.C'è un esempio di MS SQL da qualche parte su StackOverflow, dannato se riesco a vederlo in questo momento.

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

Chiama con -

exec getSomething 'John,Tom,Foo,Bar'

Immagino che Sybase dovrebbe essere in grado di fare qualcosa di simile?

È necessario utilizzare un elenco separato da virgole?Negli ultimi due anni ho preso questo tipo di idea e l'ho passato in un file XML.La "funzione" openxml prende una stringa e la rende simile a xml e quindi se crei una tabella temporanea con i dati, è interrogabile.

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))

Per quanto riguarda l'idea di Kevin di passare il parametro a una funzione che divide il testo in una tabella, ecco la mia implementazione di quella funzione di qualche anno fa.Funziona a meraviglia.

Suddivisione del testo in parole in SQL

Questo è un metodo rapido e sporco che può essere utile:

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

Non sono sicuro che sia in ASE, ma in SQL Anywhere, il sa_split_list la funzione restituisce una tabella da un CSV.Ha argomenti facoltativi per passare un delimitatore diverso (il valore predefinito è una virgola) e una lunghezza massima per ogni valore restituito.

funzione sa_split_list

Il problema con le chiamate come questa:exec getSomething '"John","Tom"' è che tratta '"John","Tom"' come una singola stringa, corrisponderà solo a una voce nella tabella che è '"John","Tom"'.

Se non volessi utilizzare una tabella temporanea come nella risposta di Paul, potresti utilizzare SQL dinamico.(Presuppone v12+)

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

Dovrai assicurarti che gli elementi in @keylist siano racchiusi tra virgolette, anche se sono valori singoli.

Per toccare ciò che @Abel ha fornito, ciò che mi ha aiutato è stato:

Il mio scopo era quello di prendere ciò che l'utente finale ha inserito da SSRS e usarlo nella mia clausola dove un in (selezionare) ovviamente @icd_value_rpt sarebbe stato commentato nella mia query di dati.

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>')

poi nel mio WHERE Ho aggiunto:

(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))
)

Prova in questo modo.Funziona per me.

@itemIds varchar(max)

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

Funziona in SQL.Dichiara nel tuo GetSomething procedura una variabile di tipo XML come tale:

DECLARE @NameArray XML = NULL

Il corpo della procedura memorizzata implementa quanto segue:

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

Dall'interno del codice SQL che chiama l'SP per dichiarare e inizializzare la variabile XML prima di chiamare la procedura memorizzata:

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>'

Usando il tuo esempio, la chiamata alla procedura memorizzata sarebbe:

EXEC GetSomething @NameArray

Ho già usato questo metodo e funziona bene.Se desideri un test rapido, copia e incolla il seguente codice in una nuova query ed esegui:

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top