查询并触发事务内的执行顺序

时间:2015-03-10 10:27:42

标签: postgresql triggers sqltransaction

如果在事务内部调用了触发器,则可以保证在事务中的下一个查询开始之前完成所有触发器(非约束/非延迟触发器)。 例如,我有以下表格:

Table a
id    name    is_updated
1     alice   False
2     alice   False
3     Alice   False

在此表上定义触发器之前的行级别,如果名称字段已更新,则将is_updated设置为True。

我执行以下交易:

BEGIN;
UPDATE table_a SET name = 'Alice' WHERE name = 'alice';
UPDATE table_a SET is_updated = False WHERE is_updated = True;
COMMIT;

是否可以在所有触发器完成之前启动第二个UPDATE语句?或者触发器在带有调用触发器的语句的内部运行?

UPD1

Postgresql版本是9.3。 这里是触发器和相关的功能源:

CREATE TRIGGER a_name_update_trigger
BEFORE UPDATE OF name
FOR EACH ROW
EXECUTE PROCEDURE on_a_name_update();

CREATE OR REPLACE FUNCTION on_a_name_update()
RETURNS TRIGGER AS $$
    BEGIN
        NEW.is_updated = True;
        RETURN NEW;
    END;
$$ LANGUAGE plpgsql;

1 个答案:

答案 0 :(得分:3)

没有什么是错的,除了我认为触发器的定义应该是这样的:

CREATE OR REPLACE FUNCTION on_a_name_update()
RETURNS TRIGGER AS $$
BEGIN
  NEW.is_updated = true;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER a_name_update_trigger
BEFORE update of name ON table_a 
FOR EACH ROW
EXECUTE PROCEDURE on_a_name_update();

SQLFiddle

所以,通过执行你的查询:

BEGIN;
UPDATE table_a SET name = 'Alice' WHERE name = 'alice';
UPDATE table_a SET is_updated = False WHERE is_updated = True;
COMMIT;

最终更新符合预期:

id    name    is_updated
1    "Alice"    False
2    "Alice"    False
3    "Alice"    False

换句话说,第二次更新是在对行触发触发器后执行的(如果col名称已更新)

相关问题