sourcecode

PL/SQL 블록에서 SELECT 문을 출력할 수 있습니까?

copyscript 2023. 2. 28. 23:42
반응형

PL/SQL 블록에서 SELECT 문을 출력할 수 있습니까?

PL/SQL 블록이 출력되도록 하려면 어떻게 해야 합니까?SELECT평소와 같은 방법으로 진술하다SELECT?

예를 들면,SELECT예를 들어 다음과 같습니다.

SELECT foo, bar FROM foobar;

힌트:

BEGIN
SELECT foo, bar FROM foobar;
END;

동작하지 않습니다.

이는 Oracle 12.1 이상에서 수행할 수 있습니다.

declare
    rc sys_refcursor;
begin
    open rc for select * from dual;
    dbms_sql.return_result(rc);
end;

테스트할 DBVisualizer는 없지만, 그 지점이 시작점일 것입니다.

자세한 내용은 Oracle 12.1 New Features Guide, Oracle Base 등의 암묵적 결과 세트를 참조하십시오.

이전 버전에서는 도구에 따라 SQL*Plus에서 다음과 같은 참조 커서 바인드 변수를 사용할 수 있습니다.

set autoprint on

var rc refcursor

begin
    open :rc for select count(*) from dual;
end;
/

PL/SQL procedure successfully completed.


  COUNT(*)
----------
         1

1 row selected.

그 결과가 왜 필요한지에 따라 다르죠.

행이 1개뿐인 것이 확실하다면 암묵적인 커서를 사용합니다.

DECLARE
   v_foo foobar.foo%TYPE;
   v_bar foobar.bar%TYPE;
BEGIN
   SELECT foo,bar FROM foobar INTO v_foo, v_bar;
   -- Print the foo and bar values
   dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar);
EXCEPTION
   WHEN NO_DATA_FOUND THEN
     -- No rows selected, insert your exception handler here
   WHEN TOO_MANY_ROWS THEN
     -- More than 1 row seleced, insert your exception handler here
END;

둘 이상의 행을 선택하려면 다음 중 하나의 명시적 커서를 사용할 수 있습니다.

DECLARE
   CURSOR cur_foobar IS
     SELECT foo, bar FROM foobar;

   v_foo foobar.foo%TYPE;
   v_bar foobar.bar%TYPE;
BEGIN
   -- Open the cursor and loop through the records
   OPEN cur_foobar;
   LOOP
      FETCH cur_foobar INTO v_foo, v_bar;
      EXIT WHEN cur_foobar%NOTFOUND;
      -- Print the foo and bar values
      dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar);
   END LOOP;
   CLOSE cur_foobar;
END;

또는 다른 유형의 커서를 사용합니다.

BEGIN
   -- Open the cursor and loop through the records
   FOR v_rec IN (SELECT foo, bar FROM foobar) LOOP       
   -- Print the foo and bar values
   dbms_output.put_line('foo=' || v_rec.foo || ', bar=' || v_rec.bar);
   END LOOP;
END;

패키지에 함수를 만들고 SYS_REFCURSOR를 반환합니다.

FUNCTION Function1 return SYS_REFCURSOR IS 
       l_cursor SYS_REFCURSOR;
       BEGIN
          open l_cursor for SELECT foo,bar FROM foobar; 
          return l_cursor; 
END Function1;

익명의 블록에서요?서브쿼리 팩터링 절과 인라인 뷰에서는 가장 복잡한 상황 이외에는 PL/SQL에 의존해야 하는 경우가 거의 없기 때문에 이러한 요구가 필요하다고 생각되는 상황에 대해 자세히 설명하겠습니다.

명명된 절차를 사용할 수 있는 경우 파이프라인 함수를 사용합니다.다음으로 매뉴얼에서 발췌한 예를 나타냅니다.

CREATE PACKAGE pkg1 AS
  TYPE numset_t IS TABLE OF NUMBER;
  FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED;
END pkg1;
/

CREATE PACKAGE BODY pkg1 AS
-- FUNCTION f1 returns a collection of elements (1,2,3,... x)
FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED IS
  BEGIN
    FOR i IN 1..x LOOP
      PIPE ROW(i);
    END LOOP;
    RETURN;
  END;
END pkg1;
/

-- pipelined function is used in FROM clause of SELECT statement
SELECT * FROM TABLE(pkg1.f1(5));

select query 출력을 pl/sql로 표시하려면 명시적 커서를 사용해야 합니다.그러면 활성 데이터 세트가 유지되며 루프에서 반복하여 데이터 세트에서 레코드를 가져오는 한 각 행을 한 번에 가져오면 활성 데이터 세트의 모든 레코드가 표시됩니다.이 데이터는 표 형식으로 생성되지 않으며 결과는 일반 텍스트 형식으로 생성됩니다.이것이 도움이 되기를 바랍니다.기타 문의사항은 다음과 같습니다.

set serveroutput on;
declare
cursor c1 is
   select foo, bar from foobar;
begin
  for i in c1 loop
    dbms_output.put_line(i.foo || ' ' || i.bar);
  end loop;
end;

고전적인 "Hello World!" 블록에는 다음 명령어를 호출하는 실행 가능 섹션이 포함되어 있습니다.DBMS_OUTPUT.PUT_LINE화면에 텍스트를 표시하는 절차:

BEGIN
  DBMS_OUTPUT.put_line ('Hello World!');
END;

http://www.oracle.com/technetwork/issue-archive/2011/11-mar/o21plsql-242570.html 에서 확인하실 수 있습니다.

12c 미만의 버전에서는 "아니오"라고 대답할 수 있습니다.적어도 SQL Server에서는 그렇지 않습니다.
결과를 인쇄하거나, 결과를 표에 삽입하거나, 함수/프로시저 내에서 결과를 커서로 반환하거나, 함수에서 행 집합을 반환할 수 있습니다.
그러나 SELECT 문을 실행하려면 반드시 결과에 대해 작업을 수행해야 합니다.


SQL Server

begin
    select 1+1
    select 2+2
    select 3+3
end

/* 3개의 결과 세트가 반환되었습니다*/


오라클

SQL> begin
  2  select * from dual;
  3  end;
  4  /
select * from dual;
*
ERROR at line 2:
ORA-06550: line 2, column 1:
PLS-00428: an INTO clause is expected in this SELECT statement

Native Dynamic SQL을 사용해야 합니다.또한 다음 SQL 명령을 실행하기 위해 BEGIN-END가 필요하지 않습니다.

declare
  l_tabname VARCHAR2(100) := 'dual';
  l_val1    VARCHAR2(100):= '''foo''';
  l_val2    VARCHAR2(100):= '''bar''';
  l_sql     VARCHAR2(1000);  
begin
  l_sql:= 'SELECT '||l_val1||','||l_val2||' FROM '||l_tabname;
  execute immediate l_sql;
  dbms_output.put_line(l_sql);
end;
/

Output:
 SELECT 'foo','bar' FROM dual

즉시 실행 스테이트먼트를 사용하다

예를 들어 다음과 같습니다.

declare
 var1    integer;
var2 varchar2(200)
begin
 execute immediate 'select emp_id,emp_name from emp'
   into var1,var2;
 dbms_output.put_line(var1 || var2);
end;

질문이 오래되었지만 질문에 완벽하게 답변하는 해결책을 공유합니다.

SET SERVEROUTPUT ON;

DECLARE
    RC SYS_REFCURSOR;
    Result1 varchar2(25);
    Result2 varchar2(25);
BEGIN
    OPEN RC FOR SELECT foo, bar into Result1, Result2 FROM foobar;
    DBMS_SQL.RETURN_RESULT(RC);
END;

선택 쿼리에서 여러 행을 반환할 때 커서가 사용됩니다.따라서 집계 또는 단일 행 데이터를 원하는 경우 커서를 사용하는 대신 커서 없이 프로시저/함수를 사용할 수 있습니다.

  Create Procedure sample(id 
    varchar2(20))as 
    Select count(*) into x from table 
    where 
       Userid=id;
     End ;

그리고 나서 간단히 절차를 호출하면

   Begin
   sample(20);
   End

이는 주로 복잡한 쿼리를 래핑하고 저장하는 절차/기능을 실제로 사용하는 것으로, 같은 로직이지만 다른 데이터를 사용하여 반복적으로 조작해야 합니다.

언급URL : https://stackoverflow.com/questions/351489/is-it-possible-to-output-a-select-statement-from-a-pl-sql-block

반응형