【发布时间】:2015-02-02 14:04:41
【问题描述】:
我为一个表定义了一个BEFORE INSERT 触发器,它对于单个INSERTstatements 可以正常工作,但不适用于INSERT ... SELECT 和MERGE 语句。
这些是我的数据库对象(简化):
CREATE TABLE "COMPANY" (
"ID" NUMBER NOT NULL,
"NAME" VARCHAR(100)
);
CREATE TABLE "EMPLOYEE" (
"ID" NUMBER NOT NULL,
"COMPANY_ID" NUMBER NOT NULL
);
CREATE UNIQUE INDEX "EMPLOYEE_PK" ON "EMPLOYEE" ("ID");
CREATE SEQUENCE "EMPLOYEE_SEQUENCE";
CREATE TRIGGER "BI_EMPLOYEE" BEFORE INSERT ON "EMPLOYEE"
REFERENCING NEW AS newrow FOR EACH ROW BEGIN ATOMIC
IF newrow.id IS NULL THEN
SET newrow.id = NEXT VALUE FOR employee_sequence;
END IF;
END;
如果单个 INSERTstatements 被执行,一切都按预期工作,ÌD 是从序列中获取的。但是如果我执行类似
INSERT INTO employee (company_id) SELECT id FROM company;
我得到一个错误:
integrity constraint violation: unique constraint or index violation: "EMPLOYEE_PK"
这可能意味着它尝试从序列中插入相同的键两次。
我正在使用 HSQLDB 的最新版本 2.3.2。
【问题讨论】:
-
您知道您可以将
employee.id列定义为generated by default as identity,这将完全消除对触发器的需求。 -
@a_horse_with_no_name 是的,但不幸的是我必须反映oracle数据库的结构(这是用于单元测试的)。所以我一定要使用一个序列。
-
一开始就使用不同的 DBMS 进行单元测试是错误的。这只是 DBMS 之间的许多差异(有时很明显,有时非常微妙)的一个示例。针对不同 DBMS 运行的单元测试并不是真正的有效测试。
-
但在我看来它确实像一个错误。如果您将其发布到 HSQLDB 讨论组,您可能会得到更好的回应:sourceforge.net/p/hsqldb/discussion/73674(尽管 Fred 也读过 SO)
-
好的,谢谢。我理解你的意思,但 HSQLDB 及其“Oracle 语法”选项到目前为止做得很好。对 oracle 数据库(而不是嵌入式数据库)进行单元测试真的很困难,尤其是在多个不同的主机(开发人员机器、jenkins 等)上运行测试时。
标签: sql database hsqldb triggers