oracle触发器疑问
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle触发器疑问相关的知识,希望对你有一定的参考价值。
exception
when others then
raise;
这几行是什么 意思?
为什么我 end 后面要加上触发器的名字,不然会报错?
首先, 那个 exception when others then 意思是, 发生了前面没有捕获的异常的情况下, 做什么处理。
下面是一个简单的例子。
2 p_test_val INT;
3 BEGIN
4 -- 导致一个 除零错误
5 p_test_val := 1024 / 0;
6 dbms_output.put_line(TO_CHAR(p_test_val));
7
8 EXCEPTION
9 WHEN OTHERS THEN
10 -- 异常自己处理
11 dbms_output.put_line('Exception Happen!');
12 END;
13 /
Exception Happen!
PL/SQL procedure successfully completed.
然后 raise 是抛出一个异常的意思。
下面是一个例子
2 -- 测试异常.
3 e_test_exception EXCEPTION;
4 BEGIN
5
6 -- 直接抛出异常,测试下面的捕获
7 RAISE e_test_exception;
8
9 EXCEPTION
10 WHEN e_test_exception THEN
11 dbms_output.put_line('Test Error !');
12 WHEN OTHERS THEN
13 dbms_output.put_line('OTHERS Error!');
14 END;
15 /
Test Error !
PL/SQL procedure successfully completed.
最后。 在触发器里面, 上面的那段代码, 就是意味着, 如果触发器处理出错了, 那么向外抛出异常。
这样, 外部语句检测到异常了, 那么就会 回滚本次修改,恢复到数据 未发生修改的情况下。
下面是一个例子
触发器实现数据完整性的处理1-- 货物表
CREATE TABLE Goods(
id INT,
Amount INT
);
-- 订单表
CREATE TABLE OrderDetail(
ID INT,
GoodsID INT,
Amount INT
);
-- 库存测试数据:
INSERT INTO Goods VALUES (1, 100);
要求:当订单表插入数据的时候,自动去货物表检查,是否有足够的库存
如果有,那么更新 货物表 的 库存 = 原库存 – 本次订单数量
如果库存不足,抱错返回.
CREATE OR REPLACE TRIGGER BeforeInsertDetail
BEFORE INSERT ON OrderDetail
FOR EACH ROW
DECLARE v_nowCount INT;
BEGIN
SELECT
Amount INTO v_nowCount
FROM
Goods
WHERE
ID = :new.GoodsID;
IF v_nowCount - :new.Amount < 0 THEN
RAISE_APPLICATION_ERROR(-20000, '库存不足!');
ELSE
UPDATE
Goods
SET
Amount = Amount - :new.Amount
WHERE
ID = :new.GoodsID;
END IF;
END;
SQL> INSERT INTO OrderDetail VALUES(1, 1, 90);
已创建 1 行。
SQL> INSERT INTO OrderDetail VALUES(1, 1, 20);
INSERT INTO OrderDetail VALUES(1, 1, 20)
*
第 1 行出现错误:
ORA-20000: 库存不足!
ORA-06512: 在 "TEST.BEFOREINSERTDETAIL", line 11
ORA-04088: 触发器 'TEST.BEFOREINSERTDETAIL' 执行过程中出错
SQL> select * from goods;
ID AMOUNT
---------- ----------
1 10
SQL> select * from OrderDetail;
ID GOODSID AMOUNT
---------- ---------- ----------
1 1 90
请注意, 当第2次更新的时候, 由于触发器代码里面, 抛异常了, 因此, 插入的更新操作将不生效。
参考技术A 当执行过程中产生异常(任何异常)时,跳转到exception语句块,执行raise操作。end后面加上触发器名是Oracle定义程序模块的规范,表示该触发器执行过程语句块在此结束。
oracle数据库中的number数据类型疑问
如果有一个字段是number类型,字段可以为空,我什么值都没有穿过去,数据库中的这个字段,会自动为0吗?
还是为null。
数据库中的number需要注意什么地方啊?
定义时注明小数位例如 number(18,4) 4即为小数位。
想要默认值是0可以在定义字段时候在后面加上default 0
例 create table test(
id number(10,2)default 0,
name varchar2(20)
);
再执行insert into test(name) values('a');后
查询 select id from test where name='a';
结果就是0.00 参考技术A 不加默认值当然不会自动为0了。读取的时候值为NULL。
定义时注明小数位例如 number(18,4) 4即为小数位。 参考技术B number类型的定义格式:number(5, 3)
其中,5代表所定义的总长度。3代表小数数位所占的长度。 参考技术C 不错,回答的很好哦
以上是关于oracle触发器疑问的主要内容,如果未能解决你的问题,请参考以下文章