删除联结/联接表引用的记录的可接受方法是什么?

时间:2009-09-25 14:39:20

标签: sql foreign-keys junction

我有三个表如下,没有级联关系(我不想这样,因为数据库主要由NHibernate管理)。

Invoice
(
    entity_id int not null,
    ...
)

Ticket
(
    entity_id int not null,
    ...
)

InvoiceTicket
(
    InvoiceId --> Not-null foreign key to Invoice.entity_id
    TicketId --> Not-null Foreign key to Ticket.entity_id
)

我要做的是删除在Ticket上给出条件的发票,票证和相关的InvoiceTicket行。但是我必须在我们的应用程序外部执行此操作,因此我为什么要构建SQL查询来执行此操作。

我已经删除了Invoice和Ticket的所有依赖项,没问题。由于InvoiceTicket引用了Invoice和Ticket,因此我必须先删除InvoiceTicket行。但是,如果我这样做,那么我对发票表的链接就会被破坏(我仍然可以删除感兴趣的门票,但不再是发票)。

使用SQL执行此操作的可接受方法是什么?

我已经通过使用临时表并使用InvoiceTicket表中感兴趣的行填充它来解决问题,但是其他人在解决此类问题方面做了什么?我想你也可以用存储过程做到这一点,但我对编写它们并不熟悉。是否有直接的方法通过SQL查询执行此操作?

5 个答案:

答案 0 :(得分:2)

嗯,这就是我要做的事情:

BEGIN TRANSACTION
    DELETE FROM InvoiceTicket
    WHERE EXISTS(
        SELECT *
        FROM TICKET t
        WHERE {t.* conditions are met}
        )

    DELETE FROM Ticket
    WHERE {t.* conditions are met}

    DELETE FROM Invoice
    WHERE NOT EXISTS(
        SELECT *
        FROM InvoiceTicket it
        WHERE Invoice.entity_id = InvoiceTicket.InvoiceId
        )
COMMIT TRANSACTION

有效地指出,这种方法(上述)仅在发票需要至少一张相关票证时才有效。虽然这是事实,但它也提出了相反的问题,你真的想要删除与匹配票证相关的每张发票吗?因为它们也可能与其他未删除的票证相关联。

答案 1 :(得分:0)

您可以将InvoiceTicket中的行放入临时表中,然后从临时表中的ID中删除InvoiceTicket,Ticket和最后的Invoice。最后吹掉临时桌子。

答案 2 :(得分:0)

我不知道所有DBMS是否支持它,但在mySQL中,您可以从表上的JOIN中删除。类似的东西:

DELETE Invoice, Ticket, InvoiceTicket
FROM Invoice, InvoiceTicket, Ticket
WHERE (condition on Ticket) 
  AND Ticket.Id = InvoiceTicket.TicketId 
  AND InvoiceTicket.InvoiceId = Invoice.Id

答案 3 :(得分:0)

如果发票可以有效存在而没有相关的发票,那么RBarryYoung的解决方案就是垃圾。它会删除所有此类发票。

在这种情况下,为了正确确定要删除的发票集,您必须首先查询它们并将它们放在一边。

答案 4 :(得分:-1)

有效地指出,如果发票本身没有被删除的发票,那么删除发票本身可能会产生问题。

虽然如此,我想指出,我无意中建议(并且我实际上已经说过),要删除的发票集应该相等到发票集合,其ID可以在任何要删除的invoiceticket中找到。

如果有人认为我的信息意味着这一点,我想警告那些人不要太容易和太急切地做出假设的危险。