2

I have three tables as follows, with NO cascading relationships (I do not want this, as the database is primarily managed by 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
)

What I'm trying to do is delete the invoices, tickets, and related InvoiceTicket rows given a criteria on Ticket. But I have to do this externally to our application, hence why I'm building a SQL query to do it.

I've already deleted all the dependencies to both Invoice and Ticket, no problem. Since Invoice and Ticket are referenced by InvoiceTicket, I must delete InvoiceTicket rows first. However, if I do that, then my link to the Invoice table is broken (I can still delete the tickets of interest, but no longer the invoices).

What is the accepted method to perform this operation using SQL?

I solved the problem already by using a temporary table and filling it with the rows of interest from the InvoiceTicket table, but what are other people doing to solve this type of problem? I would imagine you could do this with a stored procedure as well, but I'm not as familiar with writing those. Is there a direct way of doing this operation through SQL queries?

4

5 回答 5

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

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

于 2009-09-25T15:10:16.720 回答
0

如果 Invoices 可以在没有关联的 invoicetickets 的情况下有效存在,那么 RBarryYoung 的解决方案就是废话。它会删除每张此类发票。

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

于 2009-09-25T16:42:00.517 回答
0

您可以将 InvoiceTicket 中的行放入临时表中,然后从临时表中的 id 中删除 InvoiceTicket、Ticket 和最后的 Invoice。最后吹走临时表。

于 2009-09-25T14:56:20.557 回答
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
于 2009-09-25T15:12:58.947 回答
-1

已经有效地指出,如果那些发票被本身未删除的 invoicetickets 引用,则删除发票本身可能会产生问题。

虽然是真的,但我想指出的是,我没有任何地方要建议(我实际上也没有说过)要删除的发票集应该等于可以在任何 invoiceticket 中找到其 id 的发票集-待删除。

如果有人将我的信息解释为这个意思,我想警告那些人不要太容易和太急切地做出假设的危险。

于 2009-09-25T23:06:37.510 回答