1

我有 6 张桌子:

 Staff ( StaffID, Name )
 Product ( ProductID, Name )
 Faq ( FaqID, Question, Answer, ProductID* )
 Customer (CustomerID, Name, Email)
 Ticket ( TicketID, Problem, Status, Priority, LoggedTime, CustomerID* , ProductID* )
 TicketUpdate ( TicketUpdateID, Message, UpdateTime, TicketID* , StaffID* )

要回答的问题:给定一个产品 ID,删除该产品的记录。删除产品后,所有相关的常见问题解答都可以保留在数据库中,但在 ProductID 字段中应该有一个空引用。但是,删除产品也应删除任何相关的票证及其更新。为了完整起见,已删除的工单及其更新应复制到一个审计表或一组维护产品、工单和更新的历史数据的表中。(提示:您将需要定义一个或多个附加表来维护此审计信息,并在删除产品时自动复制任何已删除的工单和工单更新)。您的审计表应记录请求删除的用户和删除操作的时间戳。

我创建了额外的维护审核表:

CREATE TABLE maintain_audit(
 TicketID INTEGER NOT NULL,
 TicketUpdateID INTEGER NOT NULL,
 Message VARCHAR(1000),
 mdate TIMESTAMP NOT NULL,
 muser VARCHAR(128),
 PRIMARY KEY (TicketID, TicketUpdateID)
  ); 

另外,我创建了 1 个函数和触发器:

    CREATE OR REPLACE FUNCTION maintain_audit()
      RETURNS TRIGGER AS $BODY$
      BEGIN
      INSERT INTO maintain_audit (TicketID,TicketUpdateID,Message,muser,mdate)
     (SELECT Ticket.ID,TicketUpdate.ID,Message,user,now() FROM Ticket, TicketUpdate WHERE             Ticket.ID=TicketUpdate.TicketID AND Ticket.ProductID = OLD.ID);
      RETURN OLD;
      END;
     $BODY$
      LANGUAGE plpgsql; 


 CREATE TRIGGER maintain_audit
     BEFORE DELETE
     ON Product
     FOR EACH ROW
     EXECUTE PROCEDURE maintain_audit()

     DELETE FROM Product WHERE Product.ID=30; 

当我运行这一切时,我得到了这个:

    ERROR:  null value in column "productid" violates not-null constraint
   CONTEXT:  SQL statement "UPDATE ONLY "public"."faq" SET "productid" = NULL WHERE $1     OPERATOR(pg_catalog.=) "productid""

伙计们,你能帮我解决这个问题吗?

4

2 回答 2

2

您可能想要的是触发器。不确定您使用的是什么 RDBMS,但这就是您应该开始的地方。我从零开始,并在一个小时内启动并在类似的情况下运行触发器。

如果您还不知道,触发器会在表上发生特定类型的查询后执行某些操作,例如插入、更新或删除。您可以执行任何类型的查询。

我要给您的另一个提示是不要删除任何内容,因为这可能会破坏数据完整性。您可以只添加一个“活动”布尔字段,将活动设置为 false,然后在系统的大多数查询中将其过滤掉。或者,您可以将关联的记录移出到具有相同结构的 Products_archive 表中。易于操作:

select * into destination from source where 1=0

尽管如此,我还是会使用触发器完成您需要完成的工作,因为它们是如此自动。

于 2012-04-18T22:47:58.170 回答
1
  1. 为 Ticket.product_id 和具有 ON DELETE CASCADE 的 TicketUpdate.Ticket_id 创建外键。当您删除产品时,这将自动删除所有票证和票证更新。

  2. 使用 product_id、用户和时间戳为产品删除器创建一个审计表。工单的审计表,ticketUpdate 应该准确地反映它们。

  3. 为表 Ticket 创建一个 BEFORE DELETE TRIGGER,它将票证复制到审计表。

  4. 对 TicketUpdate 执行相同的操作

  5. 在产品上创建一个 AFTER DETETE 触发器,以捕获谁请求在产品审计表中删除产品。

  6. 在表常见问题解答中,使用 ON DELETE SET NULL 创建 Product_id 作为外键

于 2012-04-18T23:01:02.830 回答