我有三个表如下,没有级联关系(我不想这样,因为数据库主要由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查询执行此操作?
答案 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中找到。
如果有人认为我的信息意味着这一点,我想警告那些人不要太容易和太急切地做出假设的危险。