programing

동적 SQL을 실행하는 Oracle PL/SQL 익명 블록에서 결과 집합/커서를 반환하는 방법은 무엇입니까?

megabox 2023. 6. 23. 21:51
반응형

동적 SQL을 실행하는 Oracle PL/SQL 익명 블록에서 결과 집합/커서를 반환하는 방법은 무엇입니까?

다음 테이블이 있습니다.

ALLITEMS
---------------
ItemId  | Areas
---------------
1       | EAST
2       | EAST
3       | SOUTH
4       | WEST

DDL:

drop table allitems;

Create Table Allitems(ItemId Int,areas Varchar2(20));
Insert Into Allitems(Itemid,Areas) Values(1,'east');
Insert Into Allitems(ItemId,areas) Values(2,'east');
insert into allitems(ItemId,areas) values(3,'south');
insert into allitems(ItemId,areas) values(4,'east');

MSSQL에서 동적 SQL에서 커서를 가져오려면 다음 작업을 수행합니다.

DECLARE @v_sqlStatement VARCHAR(2000);
SET @v_Sqlstatement = 'SELECT * FROM ALLITEMS';
EXEC (@v_sqlStatement); --returns a resultset/cursor, just like calling SELECT 

Oracle에서는 PL/SQL 블록을 사용해야 합니다.

SET AUTOPRINT ON;
DECLARE
 V_Sqlstatement Varchar2(2000);
 outputData SYS_REFCURSOR;
BEGIN
 V_Sqlstatement := 'SELECT * FROM ALLITEMS';
 OPEN outputData for v_Sqlstatement; 
End;
--result is : anonymous block completed

**하지만 내가 얻는 것은

익명 차단이 완료되었습니다."

커서를 반환하려면 어떻게 해야 합니까?

(AUTOPRINT를 하면 REFURSOR에 정보가 출력되는 것으로 알고 있습니다(위 코드에서는 출력되지 않지만다른 문제입니다).

코드(ODBC, C++)에서 이 동적 SQL을 호출할 것이며 커서를 반환하려면 어떻게 해야 합니까?

PL/SQL 함수를 작성하여 해당 커서를 반환할 수 있습니다(또는 이와 관련된 코드가 더 있으면 해당 함수를 패키지에 넣을 수도 있습니다).

CREATE OR REPLACE FUNCTION get_allitems
  RETURN SYS_REFCURSOR
AS
  my_cursor SYS_REFCURSOR;
BEGIN
  OPEN my_cursor FOR SELECT * FROM allitems;
  RETURN my_cursor;
END get_allitems;

그러면 커서가 반환됩니다.

당신의 것을 넣지 않도록 하세요.SELECT-가능하면 PL/SQL에서 따옴표로 묶습니다.문자열로 입력하면 컴파일 시 확인할 수 없으며 사용할 때마다 구문 분석해야 합니다.


동적 SQL을 사용해야 하는 경우 쿼리를 작은 따옴표로 묶을 수 있습니다.

  OPEN my_cursor FOR 'SELECT * FROM allitems';

함수가 호출될 때마다 이 문자열을 구문 분석해야 합니다. 이 문자열은 일반적으로 속도가 느리고 런타임까지 쿼리에서 오류를 숨깁니다.

하드 구문 분석을 방지하려면 가능한 경우 bind-variables를 사용해야 합니다.

  OPEN my_cursor FOR 'SELECT * FROM allitems WHERE id = :id' USING my_id;

SQL*Plus에서 사용할 수도 있습니다.REFCURSOR변수:

SQL> VARIABLE x REFCURSOR
SQL> DECLARE
  2   V_Sqlstatement Varchar2(2000);
  3  BEGIN
  4   V_Sqlstatement := 'SELECT * FROM DUAL';
  5   OPEN :x for v_Sqlstatement;
  6  End;
  7  /

ProcÚdure PL/SQL terminÚe avec succÞs.

SQL> print x;

D
-
X

커서를 바인딩 변수(다른 DBMS의 매개 변수라고 함)로 선언할 수 있어야 합니다.

빈센트가 쓴 것처럼, 당신은 다음과 같은 것을 할 수 있습니다.

begin
  open :yourCursor
    for 'SELECT "'|| :someField ||'" from yourTable where x = :y'
      using :someFilterValue;
end;

당신은 그 스크립트에 3개의 변수를 바인딩해야 합니다."someField"에 대한 입력 문자열, "someFilterValue"에 대한 값 및 출력 변수로 선언해야 하는 "yourCursor"에 대한 커서입니다.

불행하게도, C++에서 당신이 어떻게 그럴지 전혀 모르겠습니다. (하지만, 누군가는 나에게 행운이라고 말할 수 있습니다. ;-))

어떤 액세스 라이브러리를 사용하느냐에 따라 왕실의 고통일 수도 있고 직접적일 수도 있습니다.

이 설정을 설정해야 합니다.

SET SERVEROUTPUT ON 

언급URL : https://stackoverflow.com/questions/2153053/how-to-return-a-resultset-cursor-from-a-oracle-pl-sql-anonymous-block-that-exe

반응형