本來接下來要講一下陣列型別,但內容很多,因此放到後面
5. pl/sql游標
游標:用來查詢資料庫,獲取記錄集合(結果集)的指標,當在pl/sql塊中執行查詢語句select和資料操縱語句dml時,oracle會為其分配上下文區(context area),游標指上下文區指標,對於資料操縱語句和單行select into語句來說,oracle會為他們分配隱式游標。使用顯示游標處理多行資料,也可使用select..bulk collect into 語句處理多行資料.
分類:靜態游標:
分為顯式游標和隱式游標(sql游標)。
ref游標:
是一種引用型別,類似於指標。
顯式游標:
定義:cursor 游標名 ( 引數 ) [返回值型別] is select 語句
生命週期:
1開啟游標(open):
解析,繫結。。。不會從資料庫檢索資料
2從游標中獲取記錄(fetch into):
執行查詢,返回結果集。通常定義局域變數作為從游標獲取資料的緩衝區。
3關閉游標(close)
完成游標處理,使用者不能從游標中獲取行。還可以重新開啟。
選項:引數和返回型別
舉例:在hr模式下:
set serveroutput on
declare
cursor emp_cur (p_deptid in number ) is
select * from employees where department_id=p_deptid; --定義游標
v_emp employees%rowtype;
begin
--屬於30部門的員工
dbms_output.put_line('getting employees from department 30');
open emp_cur(30); --開啟游標
loop
fetch emp_cur into v_emp; --獲取資料
exit when emp_cur%notfound;
dbms_output.put('employee id '|| v_emp.employee_id || ' is ');
dbms_output.put_line(v_emp.first_name|| ' '||v_emp.last_name);
end loop;
close emp_cur; --關閉游標
--屬於90部門的員工
dbms_output.put_line('getting employees from department 90');
open emp_cur(90);
loop
fetch emp_cur into v_emp;
exit when emp_cur%notfound;
dbms_output.put('employee id '|| v_emp.employee_id || ' is ');
dbms_output.put_line(v_emp.first_name || ' ' || v_emp.last_name);
end loop;
close emp_cur;
end;
/隱式游標(sql游標):
不用明確建立游標變數,分兩種:
1.在pl/sql中使用dml語言,使用oracle提供的名為sql的隱式游標
2.cursor for loop,用於for loop語句。
舉例:hr模式下
declare
begin
for my_dept_rec in ( select department_name, department_id from departments)
loop
dbms_output.put_line(my_dept_rec.department_id || 『 : 』 || my_dept_rec.department_name);
end loop;
end;
/sql游標有四種屬性
%found:變數最後從游標中獲取記錄的時候,在結果集中找到了記錄。
%notfound:變數最後從游標中獲取記錄的時候,在結果集中沒有找到記錄。
%rowcount:當前時刻已經從游標中獲取的記錄數量。
%isopen:是否開啟。
舉例:sql%isopen:執行時,會隱含的開啟和關閉游標.因此該屬性的值永遠都是false
sql%found:用於確定sql語句執行是否成功.當sql有作用行時,為true,否則為false
declare
v_deptno emp.deptno%type:=10;
begin
update emp set sal=sal+1 where deptno=v_deptno;
if sql%found then
dbms_output.put_line('success!');
else
dbms_output.put_line('fail!');
end if;
end;
/sql%rowcount:返回sql語句所作用的總計行數(hr模式下)
declare
begin
update departments set department_name=department_name;
--where 1=2;
dbms_output.put_line(『update 『|| sql%rowcount ||』 records』);
end;
/顯式
游標 和隱式游標的區別:
盡量使用隱式游標,避免編寫附加的游標控制**(宣告,開啟,獲取,關閉),也不需要宣告變數來儲存從游標中獲取的資料。
ref cursor游標:
動態游標,在執行的時候才能確定游標使用的查詢。分類:
強型別(限制)ref cursor,規定返回型別
弱型別(非限制)ref cursor,不規定返回型別,可以獲取任何結果集。
type ref_cursor_name is ref cursor [return return_type]
declare
type refcur_t is ref cursor;
type emp_refcur_t is ref cursor return employee%rowtype;
begin
null;
end;
/強型別舉例:
declare
--宣告記錄型別
type emp_job_rec is record(
employee_id number,
employee_name varchar2(50),
job_title varchar2(35)
);--宣告ref cursor,返回值為該記錄型別
type emp_job_refcur_type is ref cursor return emp_job_rec;
--定義ref cursor游標的變數
emp_refcur emp_job_refcur_type;
emp_job emp_job_rec;
begin
open emp_refcur for
select
e.employee_id,e.first_name||' '||e.last_name "employee_name",
j.job_title
from employees e,jobs j
where e.job_id =j.job_id and rownum <11 order by 1;
fetch emp_refcur into emp_job;
while emp_refcur%found loop
dbms_output.put(emp_job.employee_name || '''s job is ');
dbms_output.put_line(emp_job.job_title);
fetch emp_refcur into emp_job;
end loop;
close emp_refcur;
end;
/單獨select
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
begin
select empno,ename into v_empno,v_ename from emp where rownum =1;
dbms_output.put_line(v_empno||' '||v_ename);
end;
/使用into獲取值,只能返回一行。
PL SQL程式設計基礎 PL SQL簡介
課程教師 李興華 課程學習者 陽光羅諾 日期 2018 07 28 知識點 1 了解pl sql的主要特點 2 掌握pl sql塊的基本結構 pl sql語法結構 語法 declare 宣告部分,例如。定義變數 常量 游標。begin 程式編寫 sql語句 exeception 處理異常 end 說...
擴充套件方法簡介
以下是常規獲取現在時間的乙個方法。當有一天這個 yyyy mm dd 格式,有個需求需要在一千個方法中實現,你確定要寫上一千次?不會吧!於是得想辦法格式化一次便能達到目的。1 2 靜態方法,便於在main函式中呼叫.3 4static void extmethod 5 你會想到寫乙個靜態類,靜態方法...
Oracle的pl sql程式設計
1pl sql程式設計 1.1建立過程過程 create or replace procedure 引數名 in out 引數型別 沒有長度 名字 is begin pl sql程式設計語句 end 名字 ps 最有一定要加分號和斜槓 1.2呼叫 exec 過程名 引數 call 過程名 引數名 1...