복붙노트

[SQL] 그것은 PL / SQL 블록에서 SELECT 문은 출력 할 수 있습니까?

SQL

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

나는 일반 SELECT를했던 것처럼 어떻게 SELECT 문의 결과를 출력에 같은 방식으로 PL / SQL 블록을받을 수 있나요?

예를 들어, SELECT를 같이 수행하는 방법 :

SELECT foo, bar FROM foobar;

힌트 :

BEGIN
SELECT foo, bar FROM foobar;
END;

작동하지 않습니다.

해결법

  1. ==============================

    1.그것은 당신에 대한 결과를 필요에 따라 달라집니다.

    그것은 당신에 대한 결과를 필요에 따라 달라집니다.

    당신은 단지 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;
    

    당신이 1 개 이상의 행을 선택하려는 경우, 당신은 명시 적 커서를 사용할 수 있습니다 :

    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;
    
  2. ==============================

    2.당신은 오라클 12.1 이상에서이 작업을 수행 할 수 있습니다 :

    당신은 오라클 12.1 이상에서이 작업을 수행 할 수 있습니다 :

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

    내가 가진 테스트 DBVisualizer이없는,하지만 그건 아마 당신의 출발점이 될 것이다.

    자세한 내용은 오라클 12.1 처음 암시 결과 집합 참조 설명서, 오라클 자료 등을 특징

    도구에 따라 이전 버전의 경우, 당신은 SQL * 플러스에서이 예제와 심판 커서 바인드 변수를 사용할 수 있습니다 :

    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.
    
  3. ==============================

    3.익명 블록에서? 이 때문에 서브 쿼리 팩토링 조항과 당신이 가장 복잡한 상황 이외의 아무것도 PL / SQL에 의존 할 필요가 꽤 드문 인라인 전망, 즉해야 할 생각 어디 지금보다 상황에 대해 싶습니다.

    익명 블록에서? 이 때문에 서브 쿼리 팩토링 조항과 당신이 가장 복잡한 상황 이외의 아무것도 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));
    
  4. ==============================

    4.패키지에 기능을 작성하고 SYS_REFCURSOR를 반환 :

    패키지에 기능을 작성하고 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;
    
  5. ==============================

    5.고전에 "Hello World!" 블록은 화면에 표시 텍스트로 DBMS_OUTPUT.PUT_LINE 프로 시저를 호출하는 실행 가능한 부분을 포함 :

    고전에 "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

  6. ==============================

    6.당신은 PL / SQL에서 선택 쿼리 출력을 표시하려는 경우 당신은 명시 적 커서를 사용해야합니다. 이는 활성 데이터 세트를 보유하며 동시에 각 행을 인출하여 그 길이가 루프에서 반복하는 설정 데이터로부터 레코드를 페치만큼 활성 데이터 세트의 모든 레코드를 표시한다. 이 데이터는이 결과는 일반 텍스트 형식이됩니다 표 형식으로 생성되지 않습니다. 이 도움이 될 것입니다 바랍니다. 당신은 요청할 수 있습니다 다른 쿼리 ....

    당신은 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;
    
  7. ==============================

    7.12C 이하 버전의 경우, 일반 대답은 SQL 서버가 수행되고 적어도하지 않는 방식으로, NO입니다. 당신은, 당신이 테이블에 결과를 삽입 할 수 있습니다, 그 결과를 인쇄 할 수 있습니다 당신은 함수 / 프로 시저 내에서 커서로 결과를 반환 또는 함수에서 행 집합을 반환 할 수 있습니다 -  하지만 당신은 결과에 뭔가를하지 않고, SELECT 문을 실행할 수 없습니다.

    12C 이하 버전의 경우, 일반 대답은 SQL 서버가 수행되고 적어도하지 않는 방식으로, NO입니다. 당신은, 당신이 테이블에 결과를 삽입 할 수 있습니다, 그 결과를 인쇄 할 수 있습니다 당신은 함수 / 프로 시저 내에서 커서로 결과를 반환 또는 함수에서 행 집합을 반환 할 수 있습니다 -  하지만 당신은 결과에 뭔가를하지 않고, SELECT 문을 실행할 수 없습니다.

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

    / * 3 개 결과 세트가 리턴 * /

    SQL> begin
      2  select 1+1 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
    
  8. ==============================

    8.당신은 네이티브 동적 SQL을 사용해야합니다. 또한, BEGIN-END를 필요로하지 않는 SQL 명령을 실행합니다 :

    당신은 네이티브 동적 SQL을 사용해야합니다. 또한, BEGIN-END를 필요로하지 않는 SQL 명령을 실행합니다 :

    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
    
  9. ==============================

    9.사용은 즉시 문을 실행

    사용은 즉시 문을 실행

    처럼:

    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;
    
  10. ==============================

    10.문제는 오래된하지만 난 완벽하게 질문에 대한 대답 솔루션을 공유하더라도 :

    문제는 오래된하지만 난 완벽하게 질문에 대한 대답 솔루션을 공유하더라도 :

    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;
    
  11. ==============================

    11.당신의 선택 쿼리가 여러 행을 반환 할 때 커서가 사용됩니다. 그래서, 오히려 경우에 커서를 사용하여 당신은 집계 또는 단일 rowData 하행 당신이 커서없이 절차 / 기능을 사용할뿐만 아니라 같은 수하고자 할 때

    당신의 선택 쿼리가 여러 행을 반환 할 때 커서가 사용됩니다. 그래서, 오히려 경우에 커서를 사용하여 당신은 집계 또는 단일 rowData 하행 당신이 커서없이 절차 / 기능을 사용할뿐만 아니라 같은 수하고자 할 때

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

    그리고 단순히 프로 시저를 호출

       Begin
       sample(20);
       End
    

    이 절차 / 기능은 주로 배치하고 복잡한 쿼리를 저장하는 실제 사용되거나 그와 동일한 논리하지만 다른 데이터를 반복 조작을 필요

  12. from https://stackoverflow.com/questions/351489/is-it-possible-to-output-a-select-statement-from-a-pl-sql-block by cc-by-sa and MIT license