2008-08-08 41 views
16

Vì vậy, tôi có một proc lưu trữ Sybase rằng mất 1 tham số đó là một dấu phẩy tách ra danh sách các chuỗi và chạy một truy vấn với ở trong một IN() khoản:Làm cách nào để chuyển danh sách được phân tách bằng dấu phẩy sang một thủ tục được lưu trữ?

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

Làm thế nào để gọi proc lưu trữ của tôi với hơn 1 giá trị trong danh sách? Cho đến nay tôi đã cố gắng

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: Tôi thực sự thấy page này mà có một tài liệu tham khảo rất tốt trong những cách khác nhau để pas một mảng đến một sproc

+0

Tôi hy vọng bạn đã tìm được phương pháp phù hợp với mình. Trang được liên kết là danh sách các tùy chọn tốt, nhưng tôi rất vui khi thấy rằng hầu hết các tùy chọn đã được đề xuất ở đây! Phao-lô đề xuất phương pháp 2/3, các bảng tạm thời. Tôi đã đề xuất phương pháp 1, sql động. Brian và Abel đề xuất một phương pháp XML, mặc dù tôi không được cấp phép cho xml trong Sybase vì vậy không biết nếu điều đó sẽ làm việc trong Sybase. Tương tự như phương pháp 4. – AdamH

+0

bản sao có thể có của [Tham số hóa mệnh đề SQL IN?] (Http://stackoverflow.com/questions/337704/parameterizing-an-sql-in-clause) – icc97

Trả lời

3

Nếu bạn đang sử dụng Sybase 12.5 hoặc sớm hơn thì bạn không thể sử dụng chức năng này. Cách giải quyết có thể là điền một bảng tạm thời với các giá trị và đọc chúng từ đó.

0

Bạn cần phải sử dụng một dấu phẩy danh sách được phân tách? Vài năm gần đây, tôi đã dùng loại ý tưởng này và truyền vào một tệp XML. Hàm openxml "" lấy một chuỗi và làm cho nó giống như xml và sau đó nếu bạn tạo một bảng tạm thời với dữ liệu, nó có thể truy vấn được.

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

Chuyển danh sách được phân tách bằng dấu phẩy sang hàm trả về giá trị bảng. Có một ví dụ MS SQL một nơi nào đó trên StackOverflow, damned nếu tôi có thể nhìn thấy nó vào lúc này.

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

Gọi với -

exec getSomething 'John,Tom,Foo,Bar' 

Tôi đoán Sybase sẽ có thể làm điều gì đó tương tự?

0

Về ý tưởng của Kevin khi chuyển tham số đến hàm chia tách văn bản thành bảng, dưới đây là cách triển khai hàm của tôi từ vài năm trước. Làm việc một điều trị.

Splitting Text into Words in SQL

0

Đây là một phương pháp nhanh chóng và dơ bẩn có thể hữu ích:

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

Không chắc chắn nếu nó ở ASE, nhưng trong SQL Anywhere, các sa_split_list hàm trả về một bảng từ một CSV. Nó có các đối số tùy chọn để chuyển một dấu phân tách khác nhau (mặc định là dấu phẩy) và một chiều dài tối đa cho mỗi giá trị trả về.

sa_split_list function

0

Vấn đề với các cuộc gọi như thế này: exec getSomething 'John ", 'Tom'' là nó xử 'John", 'Tom'' như là một chuỗi duy nhất, nó sẽ chỉ phù hợp một mục trong bảng là "" John "," Tom "'.

Nếu bạn không muốn sử dụng bảng tạm thời như trong câu trả lời của Paul, thì bạn có thể sử dụng sql động. (Giả sử v12 +)

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

Bạn sẽ cần phải đảm bảo các mục trong @keylist có dấu ngoặc kép xung quanh, ngay cả khi chúng là giá trị đơn.

0

Điều này hoạt động trong SQL. Khai báo trong thủ tục GetSomething bạn một biến kiểu XML như vậy:

DECLARE @NameArray XML = NULL

Phần nội dung của các thủ tục lưu trữ thực hiện như sau:

CHỌN * TỪ MyTbl WHERE tên IN (SELECT ParamValues.ID.value ('.', 'VARCHAR (10)') TỪ @ NameArray.nodes ('id') AS ParamValues ​​(ID))

Từ bên trong mã SQL mà các cuộc gọi khai báo SP và khởi tạo biến XML trước khi gọi các thủ tục lưu trữ:

DECLARE @NameArray XML

SET @NameArray = '< id> NAME_1 </id> < id> NAME_2 </id> < id> NAME_3 </id> < id> Name_4 </id>'

Sử dụng ví dụ của bạn gọi đến các thủ tục lưu trữ sẽ là:

EXEC GetSomething @NameArray

Tôi đã sử dụng phương pháp này trước và nó hoạt động tốt. Nếu bạn muốn có một thử nghiệm nhanh chóng, sao chép và dán đoạn mã sau vào một truy vấn mới và thực hiện:

DECLARE @IdArray XML

SET @IdArray = '< id> NAME_1 </id> < id > NAME_2 </id> < id> NAME_3 </id> < id> Name_4 </id> '

CHỌN ParamValues.ID.value ('. '' VARCHAR (10) ') TỪ @IdArray. các nút ('id') AS ParamValues ​​(ID)

2

Đây là một chút trễ, nhưng tôi đã có vấn đề chính xác này một thời gian trước và tôi đã tìm thấy một giải pháp.

Bí quyết là trích dẫn kép và sau đó gói toàn bộ chuỗi trong dấu ngoặc kép.

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

Sửa đổi proc của bạn để khớp với mục nhập bảng vào chuỗi.

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

Tôi đã có sản phẩm này kể từ khi ASE 12.5; chúng tôi hiện đang ở trên 15.0.3.

+1

Bạn có thể muốn xem xét điều đó .. Nếu bạn có Jack trong bảng và tìm kiếm Jackie bạn sẽ thực sự nhận được Jack :) Ngoài ra nó có lẽ không phải là terribly hiệu quả, tạo ra một chuỗi cho mỗi hàng trong bảng. – JanHudecek

0

Để chạm vào những gì @Abel cung cấp, những gì đã giúp tôi hiểu là:

Mục đích của tôi là để lấy những gì từng người dùng cuối đầu vào từ SSRS và sử dụng trong mệnh đề where của tôi như là một Trong (SELECT) Rõ ràng @ICD_VALUE_RPT sẽ được nhận xét trong truy vấn Dataset của tôi.

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

sau đó trong WHERE của tôi nói thêm:

(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

Hãy thử cách này. Công trình của nó cho tôi.

@itemIds varchar(max) 

CREATE PROCEDURE getSomething @keyList varchar(4096) 
AS 
SELECT * FROM mytbl WHERE name IN (SELECT Value FROM [Global_Split] (@itemIds,',')) 
Các vấn đề liên quan