【发布时间】:2010-04-06 18:23:21
【问题描述】:
使用 Postgresql。
我尝试使用 TRIGGER 过程对 INSERT 进行一些一致性检查。
问题是……
“BEFORE INSERT FOR EACH ROW”能否保证每一行都依次插入“checked”和“inserted”?我是否需要额外的表锁定才能从并发插入中生存?
检查新的第1行->插入第1行->检查新的第2行->插入第2行
--
--
-- unexpired product name is unique.
CREATE TABLE product (
"name" VARCHAR(100) NOT NULL,
"expired" BOOLEAN NOT NULL
);
CREATE OR REPLACE FUNCTION check_consistency() RETURNS TRIGGER AS $$
BEGIN
IF EXISTS (SELECT * FROM product WHERE name=NEW.name AND expired='false') THEN
RAISE EXCEPTION 'duplicated!!!';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_check_consistency
BEFORE INSERT ON product
FOR EACH ROW EXECUTE PROCEDURE check_consistency();
--
INSERT INTO product VALUES("prod1", true);
INSERT INTO product VALUES("prod1", false);
INSERT INTO product VALUES("prod1", false); // exception!
没关系
name | expired
==============
p1 | true
p1 | true
p1 | false
这样不行
name | expired
==============
p1 | true
p1 | false
p1 | false
或者我应该问, 如何使用 Trigger 来实现类似“Primary”或“Unique”约束的 SQL。
【问题讨论】:
-
不要使用触发器,太慢且不可靠:许多事务在 SELECT 中可以看到相同的结果,因此所有事务都会正常,并且您的数据不会(部分)唯一。
标签: postgresql stored-procedures triggers