Moh*_*shi 0 oracle triggers plsql
我的触发器有什么问题?我将蟾蜍用于oracle
执行此sql蟾蜍后,显示此消息,不再!
Warning: compiled but with compilation errors
Run Code Online (Sandbox Code Playgroud)
并且触发器不起作用
我的触发器在这里:
CREATE OR REPLACE TRIGGER trg_delete_mmtp_user_feature
BEFORE DELETE
ON mmtp_user
FOR EACH ROW
BEGIN
-- for these cases delete not allowed
IF ((SELECT COUNT (*)
FROM payment p INNER JOIN mmtp_user mt
ON mt.customer_id = p.requester_id
WHERE p.rp_reason_id = 20 AND mt.mmtp_user_id = :OLD.mmtp_user_id) >
0
)
THEN
raise_application_error
(-20654,
'Query has attempted to delete MMTP_USER with existing payment'
);
ELSE --befor deleting features should be deleted
DELETE FROM mmtp_user_feature
WHERE mmtp_user_id = :OLD.mmtp_user_id;
END IF;
END;
/
Run Code Online (Sandbox Code Playgroud)
对于删除,我收到此消息:
ORA-04098: trigger 'DEVX2.TRG_DELETE_MMTP_USER_FEATURE' is invalid and failed re-validation
Run Code Online (Sandbox Code Playgroud)
出现编译错误的原因是我们无法在IF子句中使用SELECT语句。因此,您需要像这样将其分解:
....
DECLARE
n pls_integer;
BEGIN
SELECT COUNT (*)
into n
FROM payment p INNER JOIN mmtp_user mt
ON mt.customer_id = p.requester_id
WHERE p.rp_reason_id = 20 AND mt.mmtp_user_id = :OLD.mmtp_user_id
-- for these cases delete not allowed
IF n > 0
THEN
....
Run Code Online (Sandbox Code Playgroud)
解决了您的问题,正如Florin指出的那样,您将获得运行时变异表错误。当我们在触发器中放置查询时,Oracle会访问此触发器的表,从而引发Oracle错误。发生这种情况是因为表处于不稳定状态,并且查询结果是不可预测的。
突变表错误几乎总是表明数据模型不正确,而罪魁祸首是规范化不足。这意味着修复它们需要了解业务规则。在这种情况下,显而易见的解决方案是:
SELECT COUNT (*)
into n
FROM payment p
WHERE p.requester_id = :OLD.customer_id
AND p.rp_reason_id = 20
Run Code Online (Sandbox Code Playgroud)
如果user_id和之间存在一对一的关系,这将起作用customer_id。如果没有这种关系,您就必须使用对业务规则的了解来找出解决方案。
顺便说一句,使用COUNT(*)来测试是否存在并不是一种可扩展的解决方案。有很多付款的客户将花费很长时间。当您只需要他们至少有一个这样的记录时,这就是很多浪费的工作。添加and rownum = 1到查询中将减少不必要的工作。
| 归档时间: |
|
| 查看次数: |
4189 次 |
| 最近记录: |