触发器:
最近需求需要写一个触发器,整理下。。我的理解就是数据库表的监听器,,,监听对表的操作来处理一些业务上的问题(比如日志,增删改查数据库等操作。)
触发器语法
语法:
create [or replace] trigger trigger_name
{before | after} trigger_event
on table_name
[for each row]
[when trigger_condition]
trigger_body
其中:
trigger_name:触发器对象的名称。由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
before | after : 指定触发器是在触发事件发生之前触发还暗示发生之后触发
trigger_event:触发事件,在DML触发器中主要为insert、update、delete等
table_name:表名,表示发生触发器作用的对象
for each row:指定创建的是行级触发器,若没有该子句则创建的是语句级触发器
when trigger_condition:添加的触发条件
trigger_body:触发体,是标准的PL/SQL语句块
案例
--创建测试表
CREATE TABLE test(
t_id NUMBER(4),
t_name VARCHAR2(20),
t_age NUMBER(2),
t_sex CHAR
);
--创建测试表附表
CREATE TABLE ttest(
tt_id NUMBER(4),
tt_name VARCHAR2(20),
tt_age NUMBER(2),
tt_sex CHAR
);
创建触发器:插入数据的时候在另外一张表插入,更新也更新处理
CREATE OR REPLACE TRIGGER TEST_TRIGGER
AFTER DELETE OR INSERT OR UPDATE ON TEST
FOR EACH ROW
BEGIN
IF INSERTING THEN
insert into ttest(tt_id,tt_name,tt_age,tt_sex) values(:NEW.t_id,:NEW.t_name,:NEW.t_age,:NEW.t_sex);
ELSIF UPDATING THEN
IF (:NEW.t_name is not null) THEN
update ttest set tt_name = :NEW.t_name where tt_id = :NEW.t_id;
END IF;
END IF;
END;
AFTER DELETE OR INSERT OR UPDATE ON TEST 监听删除插入更新操作
FOR EACH ROW 每一行变化都触发
:new 新数据 :old 老数据
测试:
INSERT INTO TEST VALUES(119,'',22,'M');
UPDATE test SET t_age = 33 WHERE t_id = 119;
DELETE test WHERE t_id = 101;
多操作几次。。
这样一个简单的触发器就实现了。。。。其它还有很多业务场景,,但是不排除都是sql的增删改查操作。。。
触发器禁止和启用:
ALTER TRIGGER trigger_name DISABLE;
ALTER TRIGGER trigger_name ENABLE;
当然也可以手动直接删除触发器。。。。一劳永逸。。。
这里面触发器的编写用到PLSQL语法,补充其它语法使用。。。
--声明方法,定义变量
--赋值操作可以用 := 也可以使用 into 查询语句赋值
declare
i number(2):=10; --数值型变量
s varchar2(10):='小明'; --字符型变量
ena emp.ename%type; --引用型变量,直接取出emp表中ename的类型给ena
emprow emp%rowtype; --记录型变量,可以理解为可以存一行记录
begin
dbms_output.put_line(i); --输出语句
dbms_output.put_line(s);
select ename into ena from emp where empno=7788;
dbms_output.put_line(ena);
select * into emprow from emp where empno=7788;
dbms_output.put_line(emprow.ename||'的工作为:'||emprow.job);
end;
在PLSQL Developer 控制台查看结果:
--pl/sql中的if判断
--输入小于18的数字,输出未成年
--输入大于18小于40的数字,输出中年人
--输入大于40的数字,输出老年人
declare
--number给个3位表示年龄够了,最大可以是999,输入的写法 & 后根据自己喜欢写个字母
i number(3):=ⅈ
begin
if i<18 then
dbms_output.put_line('未成年');
elsif i<40 then
dbms_output.put_line('中年人');
else
dbms_output.put_line('老年人');
end if;
end;
--pl/sql中的loop循环
--用三种方式输出1到10十个数字
--while循环
declare
i number(2):=1;
begin
while i<11 loop
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
--exit循环
declare
i number(2):=1;
begin
loop
exit when i>10;
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
--for循环
declare
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
--游标:可以存放多个对象,多行记录
--输出emp表中的所有员工的姓名
declare
cursor c1 is select * from emp;
emprow emp%rowtype;
begin
open c1;
loop
fetch c1 into emprow;
exit when c1%notfound;
dbms_output.put_line(emprow.ename);
end loop;
close c1;
end;
空字符串判断
-- Created on 2012-01-04 by KANLIANHUI
declare
-- Local variables here
i varchar2(16);
begin
-- Test statements here
i:='';
dbms_output.put_line('i的值是:'|| i ||'.');
if(i='') then
dbms_output.put_line('i 是空字符串');
end if;
if(i is not null) then
dbms_output.put_line('i不为null');
end if;
if(i is null) then
dbms_output.put_line('i为null');
end if;
end;
if嵌套
if (v_compute_form = 1) then
current_fee := v_square * price; --本月费用
if (v_overdue_flag = 1) then
overdue_fine := previous_fee * 5 / 10000; --滞纳金
end if;
elsif (v_compute_form = 2) then
current_fee := record_count * price + v_plan_count1 * extra_price1 + v_plan_count2 * extra_price2 ;
end if;
增删改监听
CREATE OR REPLACE TRIGGER TEST_TRIGGER
AFTER DELETE OR INSERT OR UPDATE ON TEST
DECLARE
V_TYPE TEST_LOG.L_TYPE%TYPE;
BEGIN
IF INSERTING THEN
--INSERT触发
V_TYPE := 'INSERT';
DBMS_OUTPUT.PUT_LINE('记录已经成功插入,并已记录到日志');
ELSIF UPDATING THEN
--UPDATE触发
V_TYPE := 'UPDATE';
DBMS_OUTPUT.PUT_LINE('记录已经成功更新,并已记录到日志');
ELSIF DELETING THEN
--DELETE触发
V_TYPE := 'DELETE';
DBMS_OUTPUT.PUT_LINE('记录已经成功删除,并已记录到日志');
END IF;
INSERT INTO TEST_LOG
VALUES
(USER, V_TYPE, TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss')); --USER表示当前用户名
END;
判断字符串中是否有某一个字符
declare aa varchar2 := 'wkressssdfdf';
begin
if instr(aa,'s')>0 then
dbms_output.put_line('有bais字符duzhi');
else
dbms_output.put_line('没有daos字符');
end if;
end;
大概基本上覆盖了很多场景。。。。