【问题标题】:Why this code giving me error though everything seems right?尽管一切似乎都正确,为什么这段代码给了我错误?
【发布时间】:2018-09-28 12:06:42
【问题描述】:

这是我的 3 张桌子。

Service  (Serviceid,service_type,sname,ratings,address,due_date,company)
Hotel    (hotelid,address,ratings,hotel_name,cityid)
Insurance(insuranceid,company,due_date)

每当在 Hotel 表中进行插入时,其 hotelanme、ratings、address、hotelid 也应输入到 Service 表中。

INSERT INTO HOTEL VALUES(NEXTVAL('HOTELSQ'),'123,APPLE STREET',5.0,'GRAND BHAGVATI HOTEL',1003);

这是我在 postgres 中的触发器代码。

CREATE OR REPLACE FUNCTION INSERTFORHOTEL()
RETURNS TRIGGER AS 
$$
BEGIN
INSERT INTO SERVICE(SERVICEID,SNAME,SERVICE_TYPE,RATINGS,ADDRESS) VALUES (NEW.HOTELID,NEW.HOTEL_NAME,'HOTEL',NEW.RATINGS,NEW.ADDRESS);
RETURN NEW;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER INSERTHOTEL BEFORE INSERT ON HOTEL
FOR EACH ROW EXECUTE PROCEDURE INSERTFORHOTEL();

触发器运行成功,但是当我插入上面输入的记录时,它会出现以下错误。

ERROR:  duplicate key value violates unique constraint "service_pkey"
DETAIL:  Key (serviceid)=(3524) already exists.
CONTEXT:  SQL statement "INSERT INTO SERVICE(SERVICEID,SNAME,SERVICE_TYPE,RATINGS,ADDRESS) VALUES (NEW.HOTELID,NEW.HOTEL_NAME,'HOTEL',NEW.RATINGS,NEW.ADDRESS)"
PL/pgSQL function insertforhotel() line 3 at SQL statement
SQL state: 23505

并且没有输入记录..

我为保险表做了同样的事情。在保险表中添加一条记录也将在服务表中插入记录,它已经成功完成。 但是酒店的桌子还在..

【问题讨论】:

  • 也许您已经有一个 serviceid=3524 的条目?
  • 不,它说它有条目,但是服务表有带有保险ID的条目,因为每当我添加保险记录时,它都会成功插入服务表,但酒店条目没有插入服务表。
  • hotelid 保存为serviceid 听起来不对。您确定不想将serviceID 作为一个序列,并且每个service 行都包含一个不唯一的hotelid,它是hotel 表的外键吗? (即它使每家酒店能够提供超过 1 项服务)
  • 啊,所以你正在使用两个序列来喂一张桌子,现在它们已经发生了碰撞。您需要审查您的设计
  • 那么您不能对酒店使用一个序列,而对保险使用另一个序列。您可以使用 1 个 serviceSequence 来提供所有表(但同样,这听起来是错误的,即使是简单的语言)

标签: postgresql triggers insert


【解决方案1】:

如果hotelinsurance 两者的触发代码相同,那么您可能有一个相互矛盾的概念。

您将INSURANCE_ID 添加为SERVICE_ID 以及将HOTEL_ID 添加为SERVICE_IDINSURANCE_IDHOTEL_ID 都是序列。因此,如果insurance 表中有新的第 42 行,则将 42 作为SERVICE_ID 添加到service 表中。但是,如果您将第 42 行添加到 hotel 表中,您就会遇到问题,因为您无法再将 42 作为 SERVICE_ID 添加到您的表中。它已经存在于您的 insurance 输入中。这是一个独特的约束违规。

您最好不要将您的 ID 复制为新的 SERVICE_ID。创建一个自己的 SERVICE_ID 列(类型 serial - 或在 Postgres 10 和更高版本GENERATED AS IDENTITY 的情况下),然后您可以将其他 ID 作为引用到单独的列中,而无需唯一约束.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多