EXECUTE IMMEDIATE in plsql

前端 未结 4 1758
我在风中等你
我在风中等你 2020-12-16 08:56

How to get a result from this code

EXECUTE IMMEDIATE \'SELECT * FROM \' || table_name

through for loop

The usual m

4条回答
  •  鱼传尺愫
    2020-12-16 09:34

    Here is a simple function which dynamically opens a cursor variable, using the passed table name parameter.

    create or replace function get_details_by_dno
        ( p_tab in user_tables.table_name%type
          , p_dno in dept.deptno%type )
        return sys_refcursor
    is
        rv sys_refcursor;
        stmt varchar2(32767);
    begin
        stmt := 'select * from '
            ||p_tab
            ||' where deptno = :1';
        open rv for stmt using p_dno;
        return rv;
    end;
    /
    

    It also uses the DEPTNO as a filter; consequently the function will fail if we pass a table which doesn't have such a column.

    Some clients can interpret the ref cursor's metadata. For instance JDBC and ODBC ResultSets can do this. SQL*Plus can do it:

    SQL> exec :rc := get_details_by_dno('DEPT', 50)
    
    PL/SQL procedure successfully completed.
    
    SQL> print rc
    
        DEPTNO DNAME          LOC           REGION
    ---------- -------------- ------------- ----------
            50 HOUSEKEEPING   INTERNAL
    
    SQL> exec :rc := get_details_by_dno('EMP', 50)
    
    PL/SQL procedure successfully completed.
    
    SQL> exec :rc := get_details_by_dno('EMP', 50)
    
    PL/SQL procedure successfully completed.
    
    SQL> print rc
    
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
    ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
          8085 TRICHLER   PLUMBER         8061 08-APR-10       3500                    50
          8060 VERREYNNE  PLUMBER         8061 08-APR-08       4000                    50
          8061 FEUERSTEIN PLUMBER         7839 27-FEB-10       4500                    50
          8100 PODER      PLUMBER         8061                 3750                    50
    
    SQL>
    

    PL/SQL cannot do this. So we need to be explicit about the table and column names.

    create or replace procedure print_details_by_dno
        ( p_tab in user_tables.table_name%type
          , p_dno in dept.deptno%type )
    is
        rc sys_refcursor;
        emp_rec emp%rowtype;
        dept_rec dept%rowtype;
    begin
        rc :=  get_details_by_dno( p_tab , p_dno );
    
        if p_tab = 'EMP' then
            fetch rc into emp_rec;
            while rc%found loop
                dbms_output.put_line('ename='||emp_rec.ename||' empno='||emp_rec.empno);   
                fetch rc into emp_rec;
            end loop;
        elsif p_tab = 'DEPT' then
            fetch rc into dept_rec;
            while rc%found loop
                dbms_output.put_line('dname='||dept_rec.dname);   
                fetch rc into dept_rec;
            end loop;
        end if;
    end;
    /
    

    Let's see it running:

    SQL> set serveroutput on
    SQL> exec print_details_by_dno('EMP',50)
    ename=TRICHLER empno=8085
    ename=VERREYNNE empno=8060
    ename=FEUERSTEIN empno=8061
    ename=PODER empno=8100
    
    PL/SQL procedure successfully completed.
    
    SQL> exec print_details_by_dno('DEPT',50)
    dname=HOUSEKEEPING
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

提交回复
热议问题