NO IMAGE

利用for遍歷遊標:

declare
cursor emplist(minsal number) is select * from emp where sal > minsal;
emprow emp%rowtype;
begin
--open emplist;
for emprow in emplist(2000) loop
dbms_output.put_line(emprow.ename || '==' || emprow.sal);
end loop;
end;

此處注意:如果我們使用fetch 需要愛前面進行open操作
如果使用for,就不需要open,for可以幫我們自動open遊標。

plsql異常:

plsql提供了異常機制,當哦我們程式發生異常的時候我們可以進行捕獲,並且控制其相應的邏輯

declare
v_name emp.ename%type;
begin
select ename into v_name from emp ;
dbms_output.put_line(v_name);
exception
when others  then
dbms_output.put_line('others....');
end;

觸發器:
觸發器在資料庫裡以獨立的物件儲存,它與儲存過程和函式不同的是,儲存過程與函式需要使用者顯示呼叫才執行,而觸發器是由一個事件來啟動執行。即觸發器是當某個事件發生時自動地隱式執行

對於我們資料來說,在我們對資料進行增、刪、改的時候的可能需要進行一些具體的驗證或者阻擋操作。 check(‘男’ or ‘女’)
1、觸發器分為前置觸發器和後置觸發器
2、按型別分為 update 、insert、 delete

create or replace trigger stu_trigger 
before insert  on student1 
for each row
when (new.sid > 0)
declare
begin
dbms_output.put_line('student插入資料了。。。');
end;
此處注意:增加和刪除不能使用  of  列名這種寫法,只有修改的時候才能

觸發器關鍵自 new old

:new:就代表DML執行成功之後的表名
old :就代表執行DML成功之前的表名

觸發器通常用於級聯操作,或者限制表的操作(約束) 非空,檢查。唯一

所謂的級聯操作就是關聯操作的一種體現,當兩張表有外來鍵關係, 我們刪除資料的時候需要考慮該條資料是否被另外一張表引用
所謂的級聯操作就是操作兩張又外來鍵關係的表。

---級聯操作
create or replace trigger banji_tri_delete 
before delete on banji
for each row
when (old.bianhao>0)
declare
bianhao number := :old.bianhao;
begin
delete from student1 where  banji = bianhao;    
end;
delete from banji where bianhao = 2
--限制操作
create or replace trigger stu_trigger_update
before update of ssex on student1
for each row
when (new.sid>0)
declare
begin
if (:new.ssex <> '男' and :new.ssex != '女') then
raise_application_error(-20000, '性別必須是男或者女');
end if;
end;

行級觸發器、表級觸發器

行級:就沒操作一行觸發器就執行依次 for each row
表級: 無論操作多少行,觸發器只執行依次。 去掉for each row (不常用)

利用遊標:儲存過程實現sql分頁

-- 利用過程 遊標實現分頁
-- 定義包(遊標資料型別)
create package pkg_query 
as
type cur_query is ref cursor;
end pkg_query;
create or replace procedure pager(v_start in number, v_end in number, 
v_data out pkg_query.cur_query)
is
v_sql varchar(300);
v_row emp%rowtype;
begin
v_sql := 'select ename from (select t.*, rownum as r from (select * from emp order by hiredate desc) t) t1 where t1.r>'||v_start||' and t1.r<='||v_end;
open v_data for v_sql;
execute immediate v_sql;
end;
declare 
v_data  pkg_query.cur_query;
v_ename varchar2(20);
begin  
pager(5,10,v_data);
loop
fetch v_data into v_ename ;
dbms_output.put_line(v_ename);
exit when v_data%notfound;
end loop;
end;
--分頁語句
select ename from 
(select t.*, rownum as r from (select * from emp order by hiredate desc) t) t1
where
t1.r>5 and t1.r<=10