【发布时间】:2016-11-24 03:00:00
【问题描述】:
我需要做一个触发器,它将删除相关表中的相关行。是的,我知道 ON DELETE CASCADE,但问题是我需要使用触发器来完成。我用谷歌搜索了几个小时,但没有找到 Postgesql 的解决方案。我使用 postgresql 9.4,pgAdmin III。
我有以下表格:
CREATE TABLE "Customer"
(
"Id" serial NOT NULL,
"ContactPerson" text NOT NULL,
"Address" text NOT NULL,
"PhoneNumber" "PhoneNumber" NOT NULL,
CONSTRAINT "CustomerId (PK)" PRIMARY KEY ("Id")
)
WITH (
OIDS=FALSE
);
CREATE TABLE "Order"
(
"Id" serial NOT NULL,
"OrderDate" date NOT NULL DEFAULT ('now'::text)::date,
"Amount" integer NOT NULL DEFAULT 1,
"CustomerId" integer NOT NULL,
"GoodId" integer NOT NULL,
CONSTRAINT "OrderId (PK)" PRIMARY KEY ("Id"),
CONSTRAINT "CustomerId (FK)" FOREIGN KEY ("CustomerId")
REFERENCES "Customer" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "GoodId (FK)" FOREIGN KEY ("GoodId")
REFERENCES "Good" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "AmountCheck" CHECK ("Amount" > 0),
CONSTRAINT "OrderDateCheck" CHECK ("OrderDate" <= 'now'::text::date)
)
WITH (
OIDS=FALSE
);
我使用此查询创建触发器:
CREATE FUNCTION DeleteCustomerWithOrders() RETURNS trigger AS $DeleteCustomerWithOrders$
BEGIN
DELETE FROM "Order"
WHERE "Order"."CustomerId" = (SELECT "Id" FROM "Customer");
RETURN "Customer";
END;
$DeleteCustomerWithOrders$ LANGUAGE plpgsql;
CREATE TRIGGER DeleteCustomerWithOrders BEFORE DELETE ON "Customer"
EXECUTE PROCEDURE DeleteCustomerWithOrders();
查询运行良好,但我尝试从Customer 中删除行,但出现错误:
(“客户”列不存在)
文档中只有 ON INSERT 或 UPDATE 触发器的示例,它们使用RETURN NEW。我还看到在 sql-server 中使用 OLD。对我来说没有任何帮助。 WHERE也可能有错误。
更新
感谢帕特里克。这解决了第一个问题,但会导致另一个问题。
错误:记录 old 未赋值。详细信息:对于未分配的记录,未定义相关结构。
【问题讨论】:
-
无关,但是:你真的应该避免那些可怕的带引号的标识符。从长远来看,他们更麻烦,然后他们是值得的。如果你用英文发布错误信息也更好(设置
lc_messages=English) -
lc_messages=English我应该在脚本或 pgAdmin 设置中编写它?对不起,不明白,你是什么意思“可怕的引用标识符”,我的函数名?
标签: sql postgresql triggers