Oracle遊標的概念和簡單應用
阿新 • • 發佈:2019-02-04
概念: 遊標用於處理select語句的查詢結果(結果集 ResultSet) , 有些人也認為 遊標就是查詢結果 使用步驟與語法格式(非滾動遊標) 1. 宣告遊標 申明區: cursor 遊標名稱 is select語句; 2. 開啟遊標 open 遊標名稱; 3. 提取一行資料(遊標向下移動) fetch 遊標名稱 into 變數;--將遊標中的某一行賦值給一個變數! 4. 關閉遊標 close 遊標名稱; 1. 資源為什麼要關閉: 控制代碼數量 1024 2. 已關閉的資源可以重複關閉嗎? 遊標的開啟與關閉 不可重複執行, 否則報錯
例子: 定義一個遊標 , 用來存放s_emp表中的 id, last_name,salary ,然後提取遊標的前五條資料, 並列印 , 最後關閉遊標! set serveroutput on; declare /*宣告遊標*/ cursor s_emp_c is select id,last_name,salary from s_emp; /*宣告一個型別, 匹配結果集中一行的資料型別*/ type myemp is record( id s_emp.id%type, last_name s_emp.last_name%type, salary s_emp.salary%type ); /*宣告一個變數,用來承接遊標取出的資料*/ var_me myemp; begin /*開啟遊標*/ open s_emp_c; /*遊標向下移動一行, 並取出資料*/ for i in 1..5 loop fetch s_emp_c into var_me; dbms_output.put_line('這個員工的編號為:'||var_me.id||',名稱為:'||var_me.last_name||',他的月薪為:'||var_me.salary); end loop; close s_emp_c; end;
使用 遊標名稱%rowtype
定義一個遊標 , 用來存放s_emp表中的 id, last_name,salary ,然後提取遊標的前五條資料, 並列印 , 最後關閉遊標! set serveroutput on; declare /*宣告遊標*/ cursor s_emp_c is select id,last_name,salary from s_emp; /*宣告一個變數, 通過遊標名稱%rowtype 獲取一個匹配當前遊標中資料型別訂單record變數 */ var_me s_emp_c%rowtype; begin /*開啟遊標*/ open s_emp_c; /*遊標向下移動一行, 並取出資料*/ for i in 1..5 loop fetch s_emp_c into var_me; dbms_output.put_line('這個員工的編號為:'||var_me.id||',名稱為:'||var_me.last_name||',他的月薪為:'||var_me.salary); end loop; close s_emp_c; end; /
通過遊標 獲取 多個表中的資料
查詢s_dept 中的name欄位 和 s_region中的name欄位 ,通過遊標進行操作
set serveroutput on;
declare
cursor dr_c is select d.name dn,r.name rn from s_dept d,s_region r where d.region_id=r.id;
var_dr dr_c%rowtype;
begin
open dr_c;
fetch dr_c into var_dr;
dbms_output.put_line('部門名稱:'||var_dr.dn||',地區名稱:'||var_dr.rn);
close dr_c;
end;
/
遊標屬性
使用一些屬性, 進行迴圈遍歷遊標操作
1. 遊標名稱%found
如果遊標提取到了新資料 , 則返回true , 否則返回false .
2. 遊標名稱%notfound
如果遊標提取不到新資料 , 則返回true , 提取到了資料返回false
-------------------------------------------
上面的兩個屬性, 想要使用, 必須滿足兩個前提條件:
1. 遊標 必須 是開啟狀態 ! 否則出現非法遊標操作
2. 遊標 必須 執行過 fetch (遊標在結果集中任意一行) , 否則返回null
通過遊標獲取s_emp表格中的(id,last_name,salary), 獲取所有行
declare
cursor myemp is select id,last_name,salary from s_emp;
var_me myemp%rowtype;
begin
open myemp;
loop
fetch myemp into var_me;
exit when myemp%notfound;
dbms_output.put_line('員工編號:'||var_me.id||',姓名:'||var_me.last_name||',員工月薪:'||var_me.salary);
end loop;
close myemp;
end;
智慧迴圈遍歷遊標
for迴圈 , 在進行遊標的迭代時 ,
會自動定義變數,
自動開啟遊標,
自動提取資料,
自動關閉遊標 .
使用for迴圈 獲取s_emp表格中的id,last_name,salary
declare
cursor myemp is select id,last_name name,salary from s_emp;
begin
for var_me in myemp loop
/*
在這個迴圈中 , var_me就是每次迴圈迭代時的 每一行的資料
*/
dbms_output.put_line('id='||var_me.id||', name='||var_me.name||', 月薪='||var_me.salary);
end loop;
end;
/
帶引數的遊標
一個遊標在定義時 ,
可以設計,在開啟時需要傳遞引數 , 這個引數是 可以在select語句中使用的
格式:
cursor 遊標名稱(引數列表) is select語句
1. 引數的型別不能使用長度修飾 , 可以通過%type傳遞型別
2. 引數傳遞的時機:
在開啟遊標時 傳入 ,
例如:
open 遊標名稱(引數);
根據使用者輸入的id , 查詢一個員工的資訊(id,last_name_salary)
set serveroutput on;
declare
cursor myemp(var_id number) is select id,last_name name,salary from s_emp where id=var_id;
var_me myemp%rowtype;
var_input number;
begin
var_input :=&請輸入您要查詢的員工的id;
open myemp(var_input);
fetch myemp into var_me;
dbms_output.put_line(var_me.name);
close myemp;
end;
/
使用智慧迴圈時 ,如何傳遞引數
根據使用者輸入的id , 查詢員工編號大於使用者輸入的員工編號的員工的資訊(id,last_name_salary)
set serveroutput on;
declare
cursor myemp(var_id number) is select id,last_name name,salary from s_emp where id>var_id;
var_input number;
begin
var_input :=&請輸入員工的id;
for var_me in myemp(var_input) loop
dbms_output.put_line('id='||var_me.id);
end loop;
end;
/
參考遊標 ref cursor
概念:
遊標對應的select語句, 不必在申明區就指定, 可以在開啟遊標時 指定SQL語句
語法格式:
1. 申明區定義一個參考遊標的型別
type 參考遊標型別名稱 is ref cursor;
2. 定義一個變數
變數名稱 參考遊標型別;
3. 開啟遊標, 並關聯SELECT語句
open 遊標變數名稱 for 'SELECT語句';
例子:
根據使用者輸入的id , 查詢員工編號大於使用者輸入的員工編號的員工的資訊
之前進行遊標的遍歷時 ,我們通過遊標的名稱%rowtype獲取型別
在參考遊標中 時無法這樣去做的, 因為在申明區, 遊標還不知道自己的行型別
set serveroutput on;
declare
type mc is ref cursor;
var_mc mc;
-- 這個字串 , 就是用來做SQL查詢語句的
var_select varchar2(3000);
var_input number;
type myemp is record(
id s_emp.id%type,
salary s_emp.salary%type
);
var_me myemp;
begin
var_input:=&請輸入員工id;
var_select:='select id,salary from s_emp where id>'||var_input;
open var_mc for var_select;
loop
fetch var_mc into var_me;
exit when var_mc%notfound;
dbms_output.put_line('員工的id:'||var_me.id||',員工的薪資:'||var_me.salary);
end loop;
end;
/