쉼표로 구분된 목록을 저장 프로시저에 전달하는 방법은 무엇입니까?
-
08-06-2019 - |
문제
그래서 쉼표로 구분된 문자열 목록인 1개의 매개변수를 사용하고 IN() 절에서 in을 사용하여 쿼리를 실행하는 Sybase 저장 proc이 있습니다.
CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (@keyList)
목록에 2개 이상의 값이 있는 저장된 proc을 어떻게 호출합니까?지금까지 나는 노력했다
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
편집하다: 사실 이걸 찾았어요 페이지 배열을 sproc에 전달하는 다양한 방법에 대한 훌륭한 참조가 있습니다.
해결책
Sybase 12.5 이하를 사용하는 경우 함수를 사용할 수 없습니다.해결 방법은 임시 테이블에 값을 채우고 거기에서 읽는 것입니다.
다른 팁
조금 늦었지만 얼마 전에 정확한 문제가 발생하여 해결책을 찾았습니다.
비결은 큰따옴표를 사용한 다음 전체 문자열을 따옴표로 묶는 것입니다.
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에 있습니다.
쉼표로 구분된 목록을 테이블 값을 반환하는 함수에 전달합니다.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도 비슷한 일을 할 수 있을 것 같은데요?
쉼표로 구분된 목록을 사용해야 합니까?지난 몇 년 동안 저는 이런 종류의 아이디어를 받아들여 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))
텍스트를 테이블로 분할하는 함수에 매개 변수를 전달하려는 Kevin의 아이디어와 관련하여 몇 년 전 제가 해당 함수를 구현한 내용은 다음과 같습니다.대접을받습니다.
이는 유용할 수 있는 빠르고 더러운 방법입니다.
select *
from mytbl
where "," + ltrim(rtrim(@keylist)) + "," like "%," + ltrim(rtrim(name)) + ",%"
ASE에 있는지는 확실하지 않지만 SQL Anywhere에서는 sa_split_list 함수는 CSV에서 테이블을 반환합니다.여기에는 다른 구분 기호(기본값은 쉼표)와 각 반환 값의 최대 길이를 전달하는 선택적 인수가 있습니다.
다음과 같은 호출의 문제점은 다음과 같습니다.exec getSomething '"John","Tom"' 은 '"John","Tom"'을 단일 문자열로 처리하므로 테이블의 '"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의 항목이 단일 값이더라도 항목 주위에 따옴표가 있는지 확인해야 합니다.
@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))
)
이 방법을 시도해 보세요.그것은 나를 위해 작동합니다.
@itemIds varchar(max)
CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (SELECT Value FROM [Global_Split] (@itemIds,','))
이것은 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><</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>'
예제를 사용하면 저장 프로시저에 대한 호출은 다음과 같습니다.
EXEC GetSomething @NameArray
이전에 이 방법을 사용한 적이 있는데 잘 작동합니다.빠른 테스트를 원할 경우 다음 코드를 복사하여 새 쿼리에 붙여넣고 실행하세요.
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)