Qual è il metodo accettato di eliminare i record a cui fa riferimento una giunzione / unirsi al tavolo?

StackOverflow https://stackoverflow.com/questions/1477689

  •  16-09-2019
  •  | 
  •  

Domanda

Ho tre tabelle come segue, senza rapporti a cascata (io non voglio questo, come il database è principalmente gestito da 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
)

Quello che sto cercando di fare è eliminare le fatture, biglietti, e righe correlate InvoiceTicket dato un criterio sul biglietto. Ma devo fare questo esternamente alla nostra applicazione, quindi, perché sto costruendo una query SQL per farlo.

Ho già cancellato tutte le dipendenze sia per fattura e biglietteria, nessun problema. Dal momento che la Fattura e biglietteria sono referenziate InvoiceTicket, devo eliminare righe InvoiceTicket prima. Tuttavia, se lo faccio, poi il mio collegamento alla tabella fattura è rotto (Posso ancora cancellare i biglietti di interesse, ma non più le fatture).

Qual è il metodo accettato di eseguire questa operazione utilizzando SQL?

ho risolto il problema già utilizzando una tabella temporanea e lo riempie con le file di interesse da parte del tavolo InvoiceTicket, ma quali sono le altre persone facendo per risolvere questo tipo di problema? Immagino che si possa fare questo con una stored procedure pure, ma io non sono come familiarità con la scrittura quelli. C'è un modo diretto di fare questa operazione tramite query SQL?

È stato utile?

Soluzione

Se fatture può esistere senza validamente invoicetickets associati poi la soluzione di RBarryYoung è una schifezza. Si elimina ogni tale fattura.

In questo caso, al fine di correttamente determinare l'insieme delle fatture da eliminare, è necessario innanzitutto eseguire query e metterle da parte.

Altri suggerimenti

Bene, ecco come lo farei:

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

E 'stato validamente sottolineato che questo approccio (sopra) funziona solo se le fatture richiedono almeno un biglietto associato. Mentre questo è vero, si pone anche il problema inverso, che è vuoi veramente cancellare ogni fattura associati con i biglietti di corrispondenza? Perché possono anche essere associati ad altri biglietti, non eliminati pure.

Si potrebbe mettere le righe InvoiceTicket in una tabella temporanea, e quindi eliminare InvoiceTicket, biglietteria e, infine, fattura dal ids nella tabella temporanea. Infine soffiare via la tabella temporanea.

Non so se questo è supportato da tutti i DBMS, ma in MySQL, è possibile eliminare da un JOIN sui tavoli. Qualcosa di simile:

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

E 'stato validamente sottolineato che l'eliminazione delle fatture stesse potrebbe dare luogo a problemi se tali fatture sono referenziate invoicetickets che sono essi stessi non eliminato.

Mentre vero, voglio far notare che da nessuna parte ho lo scopo di suggerire (e in nessun luogo avere I effettivamente detto ) che l'insieme delle fatture-to-be-cancellato dovrebbe essere uguale per l'insieme delle fatture il cui ID può essere trovato in qualsiasi invoiceticket-to-be-cancellato.

Se qualcuno ha interpretato il mio messaggio nel senso che, vorrei mettere in guardia le persone contro i pericoli di fare ipotesi troppo facilmente e troppo entusiasmo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top