2008-08-08 188 views
16

所以我有一個的Sybase存儲過程,在一個IN()子句需要1個參數,這是一個逗號分隔的字符串列表,並運行一個查詢在:如何將逗號分隔列表傳遞給存儲過程?

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 

編輯:我居然發現這個page擁有的各種方式有很大的參考,以考績陣列,以一個存儲過程

+0

我希望你找到了適合你的方法。 鏈接的頁面是一個很好的選項列表,但我很高興看到大多數已經在這裏建議! 保羅建議方法2/3,臨時表。 我建議方法1,動態sql。 Brian和Abel提出了一種XML方法,雖然我沒有在sybase中獲得xml的許可,所以不知道這是否能在Sybase中工作。類似於方法4. – AdamH 2009-08-21 13:17:35

+0

可能重複[參數化SQL IN子句?](http://stackoverflow.com/questions/337704/parameterizing-an-sql-in-條款) – icc97 2014-02-04 15:19:53

回答

3

如果您正在使用Sybase 12.5或更早的版本,那麼你不能使用的功能。解決方法可能是用值填充臨時表並從中讀取它們。

0

你需要使用逗號分隔列表?最近幾年,我一直在採取這種類型的想法並傳入一個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

將逗號分隔列表傳遞給返回表值的函數。在StackOverflow上有一個MS SQL示例,如果我現在可以看到它,該死的。

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返回一個表。它有可選參數爲每個返回的值傳遞不同的分隔符(默認值爲逗號)和最大長度。

sa_split_list function

0

,像這樣的電話的問題:EXEC getSomething「‘約翰’,‘湯姆’」爲它的治療「‘約翰’,‘湯姆’」作爲一個字符串,它只會匹配表中的條目是'John','Tom''。

如果你不想在Paul的答案中使用臨時表,那麼你可以使用動態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))

從調用SP申報與調用存儲過程之前初始化XML變量的SQL代碼內:

DECLARE @NameArray XML

SET @NameArray ='< ID> NAME_1 </ID> < ID> NAME_2 </ID> < ID> NAME_3 </ID> < ID> NAME_4 </ID>」

使用您的例子在調用存儲過程將是:

EXEC GetSomething @NameArray

我以前也用這個方法,它工作正常。如果你想快速測試,複製下面的代碼粘貼到一個新的查詢,並執行:

DECLARE @IdArray XML

SET @IdArray ='< ID> NAME_1 </ID> < ID > NAME_2 </ID> < ID> NAME_3 </ID> < ID> NAME_4 </ID> '

SELECT ParamValues.ID.value('。 '' VARCHAR(10)') FROM @IdArray。節點('id')AS ParamValues(ID)

2

這有點晚,但我剛纔有這個確切的問題,我找到了解決方案。

訣竅是雙引號,然後將整個字符串用引號括起來。

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

修改您的proc以匹配表項與字符串。

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

我從ASE 12.5開始就在生產這款產品;我們現在在15.0.3。

0

觸及什麼@Abel提供什麼幫助我是:

我的目的就是把以往最終用戶從輸入SSRS什麼和使用,在我的where子句作爲In(SELECT) 顯然@ICD_VALUE_RPT將在我的數據集查詢中被註釋掉。

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,',')) 
相關問題