創建觸發器,以下代碼演示了插入或者修改 employees2 表中的first_name 如果等於 ‘chen’時觸發器就會執行:
create or replace trigger tri_employees2
before insert or update of first_name
on employees2
referencing NEW as newdata OLD as olddata
for each row
when (newdata.first_name=''chen'')
begin
:newdata.salary :=20000;
dbms_output.put_line(''new.salary:'' || :newdata.salary);
dbms_output.put_line(''old.salary:'' || :olddata.salary);
end;
執行以上觸發器:
insert into employees2 values(38,''SUP'',''WOR'',''chen'',''mp'',50000);
或者:
update employees2 set salary=90000,first_name=''chen'' where employee_id=38;
以下代碼演示了行級觸發器:
創建表:
drop table rowtable;
create table rowtable (id number(8) , name varchar2(100));
創建序列
create sequence rowtablesequence;
創建觸發器:
create or replace trigger set_sequence
before insert on rowtable
for each row
declare
rsequence number(8);
begin
select rowtablesequence.nextval into rsequence from dual;
:NEW.id :=rsequence;
end;
/
執行SQL語句:
insert into rowtable values(232,''scott'');
語句級別觸發器
創建表:
create table mylog(curr_user varchar2(100),curr_date date,Opera varchar2(10));
創建觸發
create or replace trigger tri_mylog
after insert or delete or update on employees2
begin
if inserting then
insert into mylog values(user,sysdate,''insert'');
elsif deleting then
insert into mylog values(user,sysdate,''delete'');
else
insert into mylog values(user,sysdate,''update'');
end if;
end;
/
INSTEAD OF 觸發器
INSTEAD OF 觸發器是在視圖上而不是在表上定義的觸發器,它是用來替換所使用實際語句的觸發器。
以下代碼創建了視圖:
create vIEw employee_job as select e.job_id,e.employee_id,e.first_name,e.last_name,j.name from employees2 e,jobs j where e.job_id = j.job_id
以下代碼創建 INSTEAD OF 觸發器。
create or replace trigger tri_vIEw
instead of insert on employee_job
for each row
begin
insert into jobs values(:new.job_id,:new.name);
insert into employees2(employee_id,first_name,last_name,job_id) values(:new.employee_id,:new.first_name,:new.last_name,:new.job_id);
end;
/
執行以下語句查看操作:
insert into employee_job values(''OTH'',43,''abc'',''dd'',''OTHER'');
模式觸發器:可以在模式級的操作上建立觸發器,如:create ,alter,drop,grant,revoke 和truncate 等 DDL語句:
以下示例對用戶所刪除的所有對象進行日志記錄。
1. 創建數據庫表:
drop table dropped_obj;
CREATE TABLE dropped_obj
(
obj_name VARCHAR2(30),
obj_type VARCHAR2(20),
drop_date DATE
);
2.創建觸發器:
CREATE OR REPLACE TRIGGER log_drop_obj
AFTER DROP ON SCHEMA
BEGIN
INSERT INTO dropped_obj
VALUES (ORA_DICT_OBJ_NAME, ORA_DICT_OBJ_TYPE, SYSDATE);
END;
/
3.創建和刪除對象:
創建對象:CREATE TABLE for_drop ( x CHAR );
刪除對象:DROP TABLE for_drop;
4.查看日志表中的信息:
SELECT * FROM dropped_obj;
數據庫級別觸發器:
創建數據庫表:
Create table database_log (startdate date,description varchar2(20));
創建觸發器:
create or replace trigger t_database
after startup on database
begin
insert into database_log values(sysdate, ''startup database'');
commit;
end;
起用和禁用觸發器:
以下代碼演示了禁用biu_emp_deptno 觸發器:
ALTER TRIGGER biu_emp_deptno DISABLE;
以下代碼演示了啟用biu_emp_deptno 觸發器:
ALTER TRIGGER biu_emp_deptno enable;
可以使用:
Alter table table_name{enable | disable} all triggers;
禁用或者起用在特定表上建立的所有觸發器。
刪除觸發器:
Drop trigger trigger_name;
查看觸發器信息,可以使用user_trigers 數據字典視圖。
Desc user_triggers
內置程序包:
DBMS_OUTPUT 程序包允許顯示PL/SQL 塊和子程序的輸出結果。
SET SERVEROUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(''打印三角形'');
FOR i IN 1..9 LOOP
FOR j IN 1..i LOOP
DBMS_OUTPUT.PUT(''*'');
END LOOP for_j;
DBMS_OUTPUT.NEW_LINE;
END LOOP for_i;
END;
/
DBMS_SQL 允許用戶使用動態SQL,構造和執行任意DML或DDL 語句:
connect yyaccp/accp as sysdba;
create procedure anyddl (s1 varchar2) as
cursor1 integer;
begin
cursor1 := dbms_sql.open_cursor;
dbms_sql.parse(cursor1, s1, dbms_sql.v7);
dbms_sql.close_cursor(cursor1);
end;
/
execute anyddl(''create table mytable(id number(8),name varchar2(20))'');
desc mytable;
execute anyddl(''drop table mytable'');
DBMS_RANDOM 用來生成隨機數。以下代碼演示了產生 10 個1 到 100 的隨機數。
DECLARE
l_num NUMBER;
counter NUMBER;
BEGIN
counter:=1;
WHILE counter <= 10
LOOP
l_num := ABS((DBMS_RANDOM.RANDOM MOD 100)) + 1;
DBMS_OUTPUT.PUT_LINE(l_num);
counter := counter + 1;
END LOOP;
END;
/
UTIL_FILE 包用於從PL/SQL 程序中讀寫操作系統文件:
以下代碼把數據寫入文件:
在 init.ora 文件中最後行加上: UTL_FILE_DIR = C:\DEVELOP
在控制台中設置: UTL_FILE_DIR = *
connect yyaccp/accp as sysdba;
create or replace procedure write_txtfile( -- 寫一個字符串到指定文本文件中
path in varchar2,
name in varchar2,
pstr in varchar2
)
as
l_output utl_file.file_type;
str varchar2(1000);
begin
l_output:=utl_file.fopen(path,name,''a'',2000); -- 每行最大字節數最多為32K bytes
--l_output:=utl_file.fopen(path,name,''w''); -- 每行最大字節數最多為1023 bytes
utl_file.put_line(l_output,pstr);
utl_file.fclose(l_output);
end;
/
execute write_txtfile(''C:\DEVELOP\'',''bfile.txt'','' bfile 寫如文件測試'');
讀取文件:
create or replace procedure read_txtfile(
path in varchar2, name in varchar2
)
as
l_output utl_file.file_type;
str varchar2(1000);
begin
l_output:=utl_file.fopen(path,name,''r'',2000); -- 每行最大字節數最多為32K bytes
--l_output:=utl_file.fopen(path,name,''r''); -- 每行最大字節數最多為1023 bytes
loop
utl_file.get_line(l_output,str);
dbms_output.put_line(str);
end loop;
exception
when no_data_found then
utl_file.fclose(l_output);
when others then
str:=sqlerrm(sqlcode);
dbms_output.put_line(str);
end;
/
execute read_txtfile(''C:\DEVELOP'',''bfile.txt'');
DBMS_ROWID 獲得ROWID 的詳細信息:
create or replace function get_rowid
(l_rowid in varchar2)
return varchar2
is
ls_my_rowid varchar2(200);
rowid_type number;
object_number number;
relative_fno number;
block_number number;
row_number number;
begin
dbms_rowid.rowid_info(l_rowid,rowid_type,object_number,relative_fno, block_number, row_number);
ls_my_rowid := ''object_number :''||to_char(object_number)||'' ''||
''Relative_fno is :''||to_char(relative_fno)||'' ''||
''Block number is :''||to_char(block_number)||'' ''||
''Row number is :''||to_char(row_number);
end;
/
顯示 ROWID
select rowid,employee_id from employees2 where employee_id=2;
select get_rowid(''AAAIA/AAKAAAADyAAB'') row_id from dual;