2008-10-28 2 views
11

IN 절을 공급하는 데 사용되는 다양한 매개 변수 값을 허용하는 Oracle 저장 프로 시저를 어떻게 만들 수 있습니까?IN 절에 대한 매개 변수가있는 Oracle 저장 프로 시저

이것은 내가 달성하고자하는 것입니다. PLSQL에서 업데이트 할 행의 기본 키 변수 목록을 전달하는 방법을 선언하는 방법을 모르겠습니다.

FUNCTION EXECUTE_UPDATE 
    (<parameter_list> 
    value IN int) 
    RETURN int IS 
BEGIN 
    [...other statements...] 
    update table1 set col1 = col1 - value where id in (<parameter_list>) 

    RETURN SQL%ROWCOUNT ; 
END; 

또한이 절차는 C#에서 호출하므로 .NET 기능과 호환되어야합니다.

덕분에, 로버트

답변

25

아마도 CSV를 사용하는 것이 요소가 문자열을 포함하지 않는다는 것을 100 % 확신 할 수 있다고 가정 할 때 가장 간단한 방법 일 것입니다.

이 작업을 수행하는 다른 방법은 아마도 사용자 지정 형식을 문자열 테이블로 만드는 것입니다. 당신의 문자열이 결코 이상 100 자 이상 없었다 가정하면, 당신은 할 수 :

CREATE TYPE string_table AS TABLE OF varchar2(100); 

그런 다음 저장 프로 시저에이 유형의 변수를 전달하고 직접 참조 할 수 있습니다. 이 같은 귀하의 경우에는, 뭔가 :

FUNCTION EXECUTE_UPDATE(
    identifierList string_table, 
    value int) 
RETURN int 
IS 
BEGIN 

    [...other stuff...] 

    update table1 set col1 = col1 - value 
    where id in (select column_value from table(identifierList)); 

    RETURN SQL%ROWCOUNT; 

END 

table() 기능을 사용하면 다음 다른 테이블처럼 처리 할 수 ​​단일 열 "COLUMN_VALUE"와 함께 테이블에 사용자 정의 유형을 전환은 (그렇게이에, 조인 케이스, subselects).

execute_update(string_table('foo','bar','baz'), 32); 

을 당신이에서 프로그래밍 방식으로이 명령을 구축 처리 할 수 ​​있으리라 믿고있어 :

이의 아름다움은 오라클이 저장 프로 시저를 호출 할 때 그래서 당신은 간단하게 쓸 수 있습니다, 당신을 위해 생성자를 만들 것입니다 기음#.

제 회사로서 제 회사에서는 문자열, 복식, 정수 등의 목록에 표준으로 정의 된 이러한 사용자 정의 유형이 많이 있습니다. 또한 이러한 유형의 Java 객체를 직접 매핑 할 수 있도록 Oracle JPublisher을 사용합니다. 주위를 둘러 보았지만 C#과 직접적인 상응하는 것을 볼 수 없었습니다. 그냥 자바 devs이 질문을 가로 질러 온 경우에 내가 언급 한 줄 알았는데.

+2

요약 - CSV는 오라클이 하나의 문자열로 취급하므로 자체적으로 작동하지 않습니다. – sarsnake

+0

'... from string_table (identifierList))이 아니어야합니다. ... '? –

-1

나는 오라클을 위해 그것을하지했지만, SQL Server와 함께 당신은 IN 절에서 사용할 수있는 테이블에 CSV 문자열을 변환하는 기능을 사용할 수 있습니다. (나는 생각한다!) 오라클이를 다시 작성하는 솔직해야

CREATE Function dbo.CsvToInt (@Array varchar(1000)) 
returns @IntTable table 
    (IntValue nvarchar(100)) 
AS 
begin 

    declare @separator char(1) 
    set @separator = ',' 

    declare @separator_position int 
    declare @array_value varchar(1000) 

    set @array = @array + ',' 

    while patindex('%,%' , @array) <> 0 
    begin 

     select @separator_position = patindex('%,%' , @array) 
     select @array_value = left(@array, @separator_position - 1) 

     Insert @IntTable 
     Values (Cast(@array_value as nvarchar)) 

     select @array = stuff(@array, 1, @separator_position, '') 
    end 

    return 
end 

그런 다음 당신은 CSV 문자열 (예 : '000100020003')에 전달하고

처럼 뭔가를 할 수
UPDATE table1 SET 
     col1 = col1 - value 
WHERE id in (SELECT * FROM csvToInt(@myParam)) 
+0

뭔가 :이 기사는 (myType 유형은 PLS_INTEGER BY mytable.row %의 형 인덱스 테이블) 연관 배열을 사용하여 PL/SQL 발동에 C에서 # 배열을 전달하는 좋은 예를 제공합니다/SQL하지만 프로 시저에 CSV 문자열로 콜렉션을 전달하는 것이 더 빠릅니다. csv 문자열은 먼저 PL/SQL에서 토큰 화되어야합니다. – tuinstoel

-1

왜 저장 프로 시저 여야합니까? 프로그래밍 방식으로 준비된 문을 작성할 수 있습니다.

+1

"update"보다 plsql 프로 시저에서 더 많은 명령문을 실행해야합니다. 나는 예제를 위해서 약간의 문제를 단순화했다. –

0

AskTom 웹 사이트에는 CSV 문자열을 구문 분석하는 함수를 만드는 방법과이 구문을 SQL Server 예제와 비슷한 방식으로 구문에 사용하는 방법이 나와 있습니다.

Asktom

1

내가 매개 변수의 변수 번호와 프로 시저를 만들 수있는 직접적인 방법이 없다는 생각을 참조하십시오. 그러나 문제에 대한 부분적인 해결책 중 일부는 here입니다.

  1. 일반적인 호출 유형이있는 경우 프로 시저 오버로드가 도움이 될 수 있습니다.
  2. 매개 변수 수에 상한이 있고 매개 변수의 유형도 미리 알고있는 경우 매개 변수의 기본값이 도움이 될 수 있습니다.
  3. 가장 좋은 옵션은 아마도 데이터베이스 커서에 대한 포인터 인 커서 변수의 사용법 일 것입니다.

불행히도 .NET 환경에 대한 경험이 없습니다.

+0

"매개 변수 개수가 가변적 인 프로 시저를 만드는 직접적인 방법이 없습니다"... 예, CREATE TYPE xxx AS TABLE of yyy를 사용하고 해당 유형을 매개 변수 유형으로 사용하십시오. – ObiWanKenobi

+0

아니요, 직접적인 해결책은 아닙니다. 어쨌든 귀하의 방법은 2008 년으로 거슬러 올라가는 대답입니다. – rics

0

왜 긴 매개 변수 목록을 사용하고 값을 테이블 생성자로로드하지 않는 것이 좋을까요? 여기에 내가이 스레드에 유용한 보탬이 될 것이라고 생각 마크 A. 윌리엄스의 다음 문서를 발견이 트릭

UPDATE Foobar 
    SET x = 42 
WHERE Foobar.keycol 
     IN (SELECT X.parm 
      FROM (VALUES (in_p01), (in_p02), .., (in_p99)) X(parm) 
      WHERE X.parm IS NOT NULL); 
관련 문제