2008-08-08 2 views
16

Так что есть Sybase ХП, которая принимает 1 параметр это разделенный запятыми список строк и выполняет запрос с ин в IN() пункта:Как передать список, разделенный запятой, в хранимую процедуру?

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

Как я называю хранимая процедура с более 1 в списке? До сих пор я пытался

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: Я на самом деле нашел page, который имеет большую ссылку различных способов па массива в sproc

+0

Надеюсь, вы нашли метод, который сработал для вас. Связанная страница - хороший список опций, но я рад видеть, что большинство из них уже предложено здесь! Пол предложил метод 2/3, временные таблицы. Я предложил метод 1, динамический sql. Брайан и Абель предлагают метод XML, хотя я не лицензирован для xml в sybase, поэтому не знаю, будет ли это работать в Sybase. Как и в методе 4. – AdamH 2009-08-21 13:17:35

+0

Возможный дубликат [Параметрирование предложения SQL IN?] (Http://stackoverflow.com/questions/337704/parameterizing-an-sql-in-clause) – icc97 2014-02-04 15:19:53

ответ

3

Если вы используете Sybase 12.5 или более ранней версии, то вы не можете использовать функции. Обходной путь может состоять в том, чтобы заполнить временную таблицу значениями и прочитать их оттуда.

0

вы должны использовать запятые Do разделенный список? Последние пару лет я принимал эту идею и передавал в XML-файл. Функция openxml принимает строку и делает ее как xml, а затем, если вы создаете временную таблицу с данными, она запрашивается.

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

Передайте список, разделенный запятыми, в функцию, которая возвращает значение таблицы. Есть пример MS SQL где-то на StackOverflow, проклятый, если я могу это увидеть в данный момент.

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

вызовов с -

exec getSomething 'John,Tom,Foo,Bar' 

Я предполагаю, что Sybase должны быть в состоянии сделать что-то подобное?

0

Что касается идеи Кевина о передаче параметра функции, которая разбивает текст на таблицу, вот моя реализация этой функции из нескольких лет назад. Работает.

Splitting Text into Words in SQL

0

Это быстрый и грязный метод, который может быть полезен:

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

Не уверен, если это в ASE, но в SQL Anywhere, то sa_split_list функция возвращает таблицу из CSV. Он имеет необязательные аргументы для передачи другого разделителя (по умолчанию это запятая) и maxlength для каждого возвращаемого значения.

sa_split_list function

0

Проблема с вызовами, как это: EXEC getSomething «„Джон“,„Томь“» в том, что это лечение «„Джон“,„Томь“» в виде одной строки, то это будет только матч запись в таблице «Джон», «Том».

Если вы не хотите использовать временную таблицу, как в ответе Павла, вы можете использовать динамический sql. (Подразумевается v12 +)

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

Вам нужно будет обеспечить пункты в @keylist есть кавычки вокруг них, даже если они одиночные значения.

0

Это работает в SQL. Признаться в вашей процедуре GetSomething переменную типа XML, как, например:

DECLARE @NameArray XML = NULL

Тело хранимой процедуры выполняет следующие действия:

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

из кода SQL, который вызывает SP декларировать и инициализировать переменную XML перед вызовом хранимой процедуры:

DECLARE @NameArray XML

SET @NameArray = '< идентификатор> name_1 </идентификатор> < идентификатор> NAME_2 </идентификатор> < идентификатор> NAME_3 </идентификатор> < идентификатор> Name_4 </идентификатор>»

Используя ваш пример вызова хранимой процедуры будет:

EXEC GetSomething @NameArray

Я использовал этот метод до и она отлично работает. Если вы хотите быстрый тест, скопируйте и вставьте следующий код в новый запрос и выполнить:

DECLARE @IdArray XML

SET @IdArray = '< идентификатор> name_1 </идентификатор> < идентификатор > NAME_2 </идентификатор> < идентификатор> NAME_3 </идентификатор> < идентификатор> Name_4 </идентификатор> '

ВЫБОР ParamValues.ID.value ('. '' VARCHAR (10) ') ОТ @IdArray. узлы ('id') AS ParamValues ​​(ID)

2

Это немного поздно, но у меня был этот точный вопрос некоторое время назад, и я нашел решение.

Трюк - это двойное цитирование, а затем завершение всей строки в кавычках.

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

Измените свой процесс, чтобы он соответствовал записи таблицы в строку.

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

У меня было это в производстве с ASE 12.5; мы сейчас на 15.0.3.

0

Коснуться на то, что при условии @Abel, что помогло мне было:

Моя цель состояла в том, чтобы принять то, что когда-либо конечный пользователь, введенный из SSRS и использовать это в моем предложении где в качестве In (SELECT) Очевидно @ICD_VALUE_RPT будет закомментирован в моем запросе 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>') 

то в моем WHERE я добавил:

(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

Попробуйте этот путь. Его работы для меня.

@itemIds varchar(max) 

CREATE PROCEDURE getSomething @keyList varchar(4096) 
AS 
SELECT * FROM mytbl WHERE name IN (SELECT Value FROM [Global_Split] (@itemIds,',')) 
Смежные вопросы