2012-04-18 55 views
1

我有6张桌子:在SQL中创建查询需要一些帮助?

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字段中应该有一个空引用。但是,产品的删除也应该删除任何关联的故障单及其更新。为了完整性,已删除的故障单及其更新应复制到审计表或一组表中,以维护产品,其故障单和更新的历史数据。 (提示:您需要定义一个或多个表来维护此审核信息,并在产品被删除时自动复制任何已删除的故障单和故障单更新)。您的审核表应记录请求删除的用户和删除操作的时间戳。

我已经创造了额外的maintain_audit表:

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) 
); 

Addittionally我已创建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"" 

GUYS,你能帮我解决这个问题吗?

回答

2

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

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

我会给你的另一个提示是不要删除任何东西,因为那样会破坏数据的完整性。你可以添加一个“active”布尔型字段,将active设置为false,然后在大多数系统查询中进行筛选。或者,您可以将关联的记录移出到具有相同结构的Products_archive表。容易做到:

select * into destination from source where 1=0 

不过,我会做你需要使用触发器的工作,因为它们是如此自动的。

+0

感谢贾斯汀!;-)这是非常有帮助! – BlackOctober 2012-04-18 23:05:00

1
  1. 为Ticket.product_id和TicketUpdate.Ticket_id创建了一个具有ON DELETE CASCADE的外键。这会在您删除产品时自动删除所有票证和ticketupdates。

  2. 使用product_id,user和timestamp为产品删除者创建审计表。 ticketUpdate的审计表应该准确地镜像它们。

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

  4. 执行相同的TicketUpdate

  5. 创建DETETE触发产品后拍照谁请求的产品在产品审核表中删除。

  6. 在表FAQ创建PRODUCT_ID与外键的DELETE SET NULL

+0

非常感谢David!;-)这非常有帮助! – BlackOctober 2012-04-18 23:04:33