1. 程式人生 > >Oralce 儲存過程 cursor、type x_cur is ref cursor、sys_refcursor 靜態遊標、強型別 弱型別動態遊標、靜態SQL 動態SQL 結合使用總結

Oralce 儲存過程 cursor、type x_cur is ref cursor、sys_refcursor 靜態遊標、強型別 弱型別動態遊標、靜態SQL 動態SQL 結合使用總結

直接上程式碼,使用的開發環境:

Oracle Database 11g Release 2(11.2.0.4.0) - Enterprise Edition,

PL/SQL Develop 12.0.7,Instantclient_12_2;

PL/SQL Develop -> New -> Test Windoow:

 

遊標 動態 遍歷 cursor 匿名塊.tst:

-- Created on 2018/12/17 by TECH01 
declare

    cursor cus_cur(in_id number) return pre_preorder%rowtype
    is
        select * from pre_preorder where id < in_id;
    cus_row pre_preorder%rowtype;

begin
    
    open cus_cur(1200);

    dbms_output.put_line(cus_cur%ROWCOUNT);     --如果遊標沒有open cus_cur(1200); ORA-01001: invalid cursor
    
    if cus_cur%found = true then
        dbms_output.put_line('cus_cur%found = true');
    end if;
    
    if cus_cur%notfound = true then
        dbms_output.put_line('cus_cur%notfound = true');
    end if;
    
    loop
        fetch cus_cur into cus_row; --ORA-01001: invalid cursor
        
        if cus_cur%found = true then
            dbms_output.put_line('loop fetch cus_cur%found = true');
        end if;
            
        if cus_cur%notfound = true then
            dbms_output.put_line('loop fetch cus_cur%notfound = true');
        end if;
        
        exit when cus_cur%notfound;
        
    end loop;

    dbms_output.put_line(cus_cur%ROWCOUNT);

    close cus_cur;

    --dbms_output.put_line(cus_cur%ROWCOUNT );  --ORA-01001: invalid cursor

end;





DBMS Output:

0
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%found = true
loop fetch cus_cur%notfound = true
14

 

遊標 動態 遍歷 ref cursor 匿名塊.tst:

-- Created on 2018/12/17 by TECH01 
declare 
  -- Local variables here
  --type cus_cur_type is ref cursor return pre_preorder%rowtype; 
  type cus_cur_type is ref cursor;
  cus_cur cus_cur_type;
  cus_row pre_preorder%rowtype;
  l_id integer := 1200;
begin
  --open cus_cur for select * from pre_preorder where id < :v_id using l_id;  --PL/SQL: ORA-00933: SQL command not properly ended
  open cus_cur for 'select * from pre_preorder where id < :v_id' using l_id;  --ref cursor return pre_preorder%rowtype; 不可以用在動態SQL語句中PLS-00455: cursor 'CUS_CUR' cannot be used in dynamic SQL OPEN statement
  --open cus_cur for select * from pre_preorder where id < l_id;              --ref cursor return pre_preorder%rowtype; 可以用在靜態SQL語句中
  
  dbms_output.put_line(cus_cur%ROWCOUNT );
  
  loop 
      fetch cus_cur into cus_row;
      exit when cus_cur%notfound;
  end loop;
  
  dbms_output.put_line(cus_cur%rowcount);
  
  
  open cus_cur for select * from pre_preorder where id < 1300;
  
  loop 
      fetch cus_cur into cus_row;
      exit when cus_cur%notfound;
  end loop;
  
  dbms_output.put_line(cus_cur%rowcount);
  
  
  close cus_cur;
  
  --dbms_output.put_line(cus_cur%rowcount);   --ORA-01001: invalid cursor
  
end;

 

遊標 動態 遍歷 sys_refcursor 匿名塊.tst:

-- Created on 2018/12/17 by TECH01 
declare

    cus_cur sys_refcursor;--return pre_preorder%rowtype;  --PLS-00103: Encountered the symbol "RETURN" when expecting one of the following: := . ( @ % ; not null range default character, The symbol ";" was substituted for "RETURN" to continue.

    cus_row pre_preorder%rowtype;
    l_id integer := 1200;
begin
    --open cus_cur for select * from pre_preorder where id < :v_id using l_id;    --PL/SQL: ORA-00933: SQL command not properly ended
    --open cus_cur for 'select * from pre_preorder where id < :v_id' using l_id;  --PLS-00455: cursor 'CUS_CUR' cannot be used in dynamic SQL OPEN statement
    --open cus_cur for 'select * from pre_preorder where id < l_id';              --ORA-00904: "L_ID": invalid identifier
    open cus_cur for select * from pre_preorder where id < l_id;                  --sys_refcursor可以用在靜態SQL語句中
    --open cus_cur for 'select * from pre_preorder where id < :v_id' using l_id;  --sys_refcursor可以用在動態SQL語句中
    
    
    
    dbms_output.put_line(cus_cur%ROWCOUNT);

    loop
        fetch cus_cur
            into cus_row;
        exit when cus_cur%notfound;
    end loop;

    dbms_output.put_line(cus_cur%ROWCOUNT);

    close cus_cur;

    --dbms_output.put_line(cus_cur%ROWCOUNT );  --ORA-01001: invalid cursor

end;



 

 

綜上總結:

1. 只有 sys_refcursor return pre_preorder%rowtype;  

不能使用強型別的動態遊標,彙報以下錯誤:

PLS-00103: Encountered the symbol "RETURN" when expecting one of the following: := . ( @ % ; not null range default character, The symbol ";" was substituted for "RETURN" to continue.

2. ref cursor return pre_preorder%rowtype;

不可以用在動態SQL語句中PLS-00455: cursor 'CUS_CUR' cannot be used in dynamic SQL OPEN statement;

可以用在靜態SQL語句中

3. sys_refcursor

可以用在靜態SQL語句中;

可以用在動態SQL語句中;

3. x_curcur%ROWCOUNT 可以理解為是一個計數器,初始值為0,每fetch遊標x_curcur一次,計數器 +1;

4. x_cur%found 在fetch遊標x_curcur前為false,fetch到資料行時為true,直到fetch不到行資料時值為false;

5.x_cur%notfound  在fetch遊標x_curcur前為false,fetch到資料行時為false,直到fetch不到行資料時值為true;

 

 

參考:

https://blog.csdn.net/zx695370759/article/details/79200913

強型別的動態遊標和弱型別的動態遊標區別

2018年01月29日 22:58:22 穿毛衣的程式猿 閱讀數:130

1、簡單的來說:強型別的動態遊標是指帶有return返回語句的,而弱型別的動態遊標是指不帶return語句的(也即,弱型別的動態遊標可以與任何查詢語句匹配,但是強型別的動態遊標只能與特定的查詢語句匹配。)

2、個人理解:強型別的有點像java中使用了泛型一樣對其進行了限制,而弱型別的就像object型別。