第八章 遊標和觸發器sql
初識遊標數據庫
在PL/SQL塊中執行SELECT、INSERT、DELETE和UPDATE語句時,ORACLE會在內存中爲其分配上下文區(Context Area),即緩衝區。遊標是指向該區的一個指針,或是命名一個工做區(Work Area),或是一種結構化數據類型。它爲應用等量齊觀提供了一種對具備多行數據查詢結果集中的每一行數據分別進行單獨處理的方法,是設計嵌入式SQL語句的應用程序的經常使用編程方式。編程
定位行,逐行跳動oracle
遊標分類函數
1. 顯式 遊標用於處理SELECT語句返回的多行數據;人爲建立,干預性能
2. 隱式 遊標用於處理SELECT INTO和非查詢的DML語句;系統自動建立,管理fetch
經常使用屬性 CURSOR設計
%ISOPEN 指針
用於肯定遊標是否已經打開。若是遊標已經打開,則返回值爲TRUE;不然返回FALSE 日誌
%FOUND
檢查是否從結果集中提取到數據。若是提取到數據,則返回值爲TRUE;不然返回FALSE
%NOTFOUND
與%FOUND屬性剛好相反,若是提取到數據,則返回值爲FALSE;不然返回TRUE
%ROWCOUNT
返回到當前行爲止已經提取到的實際行數
顯示遊標格式:
1. 定義遊標
CURSOR cursor_name IS select_SQL;
2. 打開遊標
OPEN cursor_name;
3. 提取數據
FETCH cursor_name INTO variable1,variable2,...;
當運行fetch後,遊標纔開始工做,記錄當前行,有數據則下移,而後置%FOUND,%NOTFOUND的值
4. 關閉遊標
CLOSE cursor_name;
顯示遊標:
遊標動態傳參,顯示遊標
隱式for循環遊標:
隱含遊標,當執行一條非查詢的DML語句或者SELECT...INTO語句時,都會建立一個隱含遊標
1. 隱含遊標的名稱是SQL,不能對SQL遊標顯式執行OPEN、FETCH和CLOSE語句。
2. Oracle隱式地打開、提取,並老是自動地關閉SQL遊標
3. 隱含遊標的屬性
SQL%FOUND
SQL%NOTFOUND
SQL%ROWCOUNT
SQL%ISOPEN
示例
declare
v_stuId number := '&input_stuId';
begin
delete from student where stu_id=v_stuId;
if sql%found then
DBMS_OUTPUT.PUT_LINE('找到員工');
else
DBMS_OUTPUT.PUT_LINE('未找到員工');
end if;
end;
初始觸發器
觸發器是指被隱含執行的存儲過程,它可使用PL/SQL進行開發
當發生特定事件(如修改表、建立對象、登陸到數據庫)時,Oracle會自動執行觸發器的相應代碼
觸發器的類型
一、DML觸發器
在對數據庫表進行DML(insert,update,delete)操做時觸發,而且能夠對每行或者語句操做上進行觸發。
二、替代觸發器
是oracle8專門爲進行視圖操做的一種觸發器
三、系統觸發器
對數據庫系統事件進行觸發,如啓動、關閉等
注意事項:
1. 觸發器不接受參數。
2. 一個表上最多可有12個觸發器,但同一時間、同一事件、同一類型的觸發器只能有一個。並各觸發器之間不能有矛盾。
3. 在一個表上的觸發器越多,對在該表上的DML操做的性能影響就越大。
4. 觸發器最大爲32KB。若確實須要,能夠先創建過程,而後在觸發器中用CALL語句進行調用。
5. 觸發器中不能包含事務控制語句(COMMIT,ROLLBACK,SAVEPOINT)。由於觸發器是觸發語句的一部分,觸發語句被提交、回退時,觸發器也被提交、回退了。在觸發器主體中調用的任何過程、函數,都不能使用事務控制語句。
表頭複製
CREATE TABLE dept_log AS SELECT * FROM dept WHERE 1=2;
DML觸發器
刪除示例:
create or replace trigger tr_del_student
--指定觸發時機爲刪除操做前觸發
before delete
on student
--說明建立的是行級觸發器
for each row
begin
--將修改前數據插入到日誌記錄表,要確保SQL能夠正常工做
insert into student_log values(:old.stu_id,:old.stu_name,:old.stu_age,:old.stu_sex,:old.stu_class,:old.stu_create_date);
end;
修改示例
create or replace trigger tr_update_student
--指定觸發時機爲修改操做後觸發
after update
on student
for each row
begin
-- 記錄修改後的值
insert into student_log
values(:new.stu_id,:new.stu_name,:new.stu_age,:new.stu_sex,:new.stu_class,:new.stu_create_date);
end;
刪除觸發器
drop trigger trigger_name
系統觸發器
建立日誌記錄表
create table log_event(
log_type varchar2(20),
username varchar2(20),
logonTime date,
logoffTime date
);
登陸觸發器
create or replace trigger logon_trigger
after logon on database
begin
insert into log_event(log_type,username,logonTime)
values('logon',ora_login_user,sysdate);
end;
登出觸發器
create or replace trigger logoff_trigger
before logoff on database
begin
insert into log_event(log_type,username,logoffTime)
values('logoff',ora_login_user,sysdate);
end;