sql valor ¿Cómo pasar una lista separada por comas a un procedimiento almacenado?




retornar valor stored procedure sql server (9)

No estoy seguro si está en ASE, pero en SQL Anywhere, la función sa_split_list devuelve una tabla de un CSV. Tiene argumentos opcionales para pasar un delimitador diferente (por defecto es una coma) y una longitud máxima para cada valor devuelto.

función sa_split_list

Así que tengo un procedimiento almacenado de Sybase que toma 1 parámetro que es una lista de cadenas separada por comas y ejecuta una consulta con in en una cláusula IN ():

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

¿Cómo llamo a mi proc almacenado con más de 1 valor en la lista? Hasta ahora lo he intentado

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: en realidad encontré esta página que tiene una gran referencia de las diversas formas de pasar una matriz a un sproc


Esto es un poco tarde, pero tuve este problema exacto hace un tiempo y encontré una solución.

El truco es hacer una cita doble y luego envolver toda la cadena entre comillas.

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

Modifique su proc para que coincida con la entrada de la tabla a la cadena.

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

He tenido esto en producción desde ASE 12.5; ahora estamos en 15.0.3.


Con respecto a la idea de Kevin de pasar el parámetro a una función que divide el texto en una tabla, aquí está mi implementación de esa función desde hace unos años. Funciona un placer

Dividir texto en palabras en SQL


Intenta de esta manera. Funciona para mí

@itemIds varchar(max)

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

Este es un método rápido y sucio que puede ser útil:

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

Para ver lo que proporcionó @Abel, lo que me ayudó fue:

Mi propósito era tomar lo que sea que el usuario final ingresara de SSRS y usarlo en mi cláusula where como In (SELECT) Obviamente @ICD_VALUE_RPT se comentaría en mi consulta Dataset.

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

luego en mi WHERE agregué:

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

El problema con las llamadas como esta: exec getSomething '"John", "Tom"' es que trata a '' John '', 'Tom' 'como una sola cadena, solo coincidirá con una entrada en la tabla que es' ' John "," Tom "'.

Si no quería usar una tabla temporal como en la respuesta de Paul, entonces podría usar sql dinámico. (Asume v12 +)

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

Deberá asegurarse de que los elementos en @keylist tengan comillas a su alrededor, incluso si son valores únicos.


Si usa Sybase 12.5 o una versión anterior, entonces no puede usar funciones. Una solución podría ser llenar una tabla temporal con los valores y leerlos desde allí.


¿Necesita usar una lista separada por comas? En los últimos años, he estado tomando este tipo de ideas y pasando un archivo XML. La "función" de openxml toma una cadena y la hace como xml y luego si usted crea una tabla temporal con los datos, es consultable.

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




sybase-ase