Oracle触发器 - 基于表A的条件更新表B
我试图创建一个Oracle触发器,该触发器基于触发器中运行的select语句设置表B上列的值。Oracle触发器 - 基于表A的条件更新表B
我希望能够在执行表A上的插入后,基于select语句将表B'is_active'列的值设置为'N'。
我的查询如下:
CREATE OR REPLACE TRIGGER INACTIVE_STATE
AFTER INSERT ON
COMMENTS
FOR EACH ROW
DECLARE
inactive_id number;
BEGIN
SELECT distinct b.id
into inactive_id
from comments a,
modules b
where a.module_name=b.name
and a.type_id='FUNCTIONAL'
and a.module_id=b.id;
update modules
set is_active='N'
where ID=:inactive_id
END INACTIVE_STATE;
/
当我尝试和complpile这个触发,我得到以下错误:
Error(15,1): PL/SQL: SQL Statement ignored
Error(17,10): PLS-00049: bad bind variable 'INACTIVE_ID'
Error(17,15): PL/SQL: ORA-00933: SQL command not properly ended
Error(19,1): PLS-00103: Encountered the symbol "/" when expecting one of the following: (begin case declare end exception exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge
看来它不喜欢的更新语句,或该过程中不会分析绑定变量。
如果我将这些语句分成2个命令(使用var来处理绑定变量:inactive_id),它将按预期工作。
VAR INACTIVE_ID number
begin
select distinct b.id into :INACTIVE_ID
from comments a,
modules b
where a.module_name=b.name
and a.type_id='FUNCTIONAL'
and a.module_id=b.id;
end;
/
PL/SQL procedure successfully completed.
SQL>
SQL> update modules
set is_active='N'
where ID=:INACTIVE_ID
/
1 row updated.
任何想法,我可能会忽略?
正如托尼·安德鲁斯在原岗位的评论中指出。
正确的代码应该是:
CREATE OR REPLACE TRIGGER INACTIVE_STATE
AFTER INSERT ON
COMMENTS
DECLARE
inactive_id number;
BEGIN
SELECT distinct b.id
into inactive_id
from comments a,
modules b
where a.module_name=b.name
and a.type_id='FUNCTIONAL'
and a.module_id=b.id;
update modules
set is_active='N'
where ID=inactive_id
END INACTIVE_STATE;
/
尝试使用,我用冒号正确的where子句中的“inactive_id”变量之前
PRAGMA AUTONOMOUS_TRANSACTION;
之前开始
千万别这么做! –
如果触发器具有DML语句并且您想提交事务;那么没有设置杂注自治,它不会允许你这样做。基本上,没有硬性规定。是否使用编注自主或不完全取决于要求。 –
好吧,“99%的时间,不要那样做”!我可以想到的唯一有效的情况是,如果您出于某种原因想要记录触发触发器的操作,即使您然后回滚了主事务并且实际上并未发生。如果你这样做的话,99%的时间你可能会破坏数据库。 –
where子句应该是'触发器的其中ID = inactive_id' - 没有冒号。 –
谢谢Tony,tigger编译成功!但是,执行我的更新语句时,我得到以下:表COMMENTS是变异,触发器/函数可能不会看到它 - 任何想法我如何处理这个? – Huskie69
首先,select语句的目的是什么?它是否真的应该查看所有评论,或者您刚刚插入的这个特定评论?如果所有评论你应该能够删除'FOR EACH ROW'并且避免突变问题。 –