1. 程式人生 > >Oracle的PL/SQL塊中select * from 查詢結果集

Oracle的PL/SQL塊中select * from 查詢結果集

   看到很多新手朋友想在儲存過程或者匿名塊中直接使用select * form table語句直接返回結果集,這樣子是會提示錯誤的,因為PL/SQL塊中不能用select 語句,而必須用select into。錯誤如下圖

                       

  所以想要在塊中返回結果集,可以使用遊標進行遍歷

set Serveroutput On
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
v_salary emp.sal%type;
cursor emp_cursor is
select empno,ename,sal from emp where deptno = 20;
begin
open emp_cursor;
loop
fetch emp_cursor into v_empno,v_ename,v_salary;
exit when emp_cursor%notfound;
dbms_output.put_line('編號為'||v_empno||'的員工名字為'||v_ename
||',他的薪資為'
||v_salary);
end loop;
close emp_cursor;
end;
  我這裡只是截取了emp表中的某幾個欄位,也可以直接設定emp型別的遊標值儲存變數,輸出完整的結果集。

  有同學可能會想到用動態SQL語句

DECLARE
    V_SQLSTMT VARCHAR2(300);
BEGIN
    V_SQLSTMT := 'SELECT * FROM emp WHERE empno = 7396';
    EXECUTE IMMEDIATE V_SQLSTMT;
END;

  實踐一下就能知道,這段程式碼是可以編譯成功的,然而它並不會輸出任何結果。

  也就是說即使使用動態SQL語句,也需要用到遊標。

set Serveroutput On
DECLARE
    type emp_cursor is ref cursor;
    emp_cur emp_cursor;
    v_empno emp.empno%type;
    v_ename emp.ename%type;
BEGIN
    open emp_cur for
    'select empno,ename from emp where deptno = 20';
    loop
    fetch emp_cur into v_empno,v_ename;
    exit when emp_cur%notfound;
    Dbms_Output.Put_Line(v_empno||'  '||v_ename);
    end loop;
    close emp_cur;
END;
  可以看到動態語句中使用open for進行遍歷。

  需要注意的是,動態SQL語句中的execute immediate只能處理單行查詢(如上上段程式碼),如果想不通過遊標進行遍歷,同時想用execute immediate動態語句,就必須要用批量繫結bulk collect into。這樣execute immediate就有了處理多行查詢的功能。因為是批量繫結,需要把查詢出的這麼多結果放到索引表中。