Mithilfe der temporären Tabelle in der where-Klausel
Ich löschen möchte viele Zeilen mit dem gleichen Satz von Feldern, die in einigen (6) Tabellen. Ich könnte dies tun, indem Sie löschen das Ergebnis einer Unterabfrage, die bei jeder Tabelle (Lösung 1), die überflüssig wäre, weil die Unterabfrage wäre jedes mal die gleiche; also will ich das speichern, das Ergebnis der Unterabfrage in eine temporäre Tabelle und löschen Sie den Wert jeder Zeile (von der temp-Tabelle) in den Tabellen (Lösung 2). Welche Lösung ist besser?
Erste Lösung:
DELETE FROM dbo.SubProtocols
WHERE ProtocolID IN (
SELECT ProtocolID
FROM dbo.Protocols
WHERE WorkplaceID = @WorkplaceID
)
DELETE FROM dbo.ProtocolHeaders
WHERE ProtocolID IN (
SELECT ProtocolID
FROM dbo.Protocols
WHERE WorkplaceID = @WorkplaceID
)
// ...
DELETE FROM dbo.Protocols
WHERE WorkplaceID = @WorkplaceID
Zweite Lösung:
DECLARE @Protocols table(ProtocolID int NOT NULL)
INSERT INTO @Protocols
SELECT ProtocolID
FROM dbo.Protocols
WHERE WorkplaceID = @WorkplaceID
DELETE FROM dbo.SubProtocols
WHERE ProtocolID IN (
SELECT ProtocolID
FROM @Protocols
)
DELETE FROM dbo.ProtocolHeaders
WHERE ProtocolID IN (
SELECT ProtocolID
FROM @Protocols
)
// ...
DELETE FROM dbo.Protocols
WHERE WorkplaceID = @WorkplaceID
Ist es möglich Lösung 2, ohne die Unterabfrage? Sagen tun WHERE ProtocolID IN @Protocols
(aber syntaktisch korrekten)?
Ich bin mit Microsoft SQL Server 2005.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Während Sie können, vermeiden Sie die Unterabfrage in SQL Server mit einer Verknüpfung, etwa so:
Werden Sie feststellen, dass dies nicht bekommt man wirklich jede Leistung über jede Ihrer Ansätze. In der Regel, mit Ihrem Unterabfrage, SQL Server 2005 optimiert, dass
in
in eineinner join
, da es sich nicht auf jeder Zeile. Auch die SQL-Server-wird wohl der cache der Unterabfrage in Ihrem Fall, so schob Sie es in eine temp-Tabelle ist wahrscheinlich unnötig.Den ersten Weg, obwohl, wäre anfällig für Veränderungen in
Protocols
während der Transaktionen, bei denen die zweite nicht. Nur etwas zu denken.Können versuchen, diese
DELETE ... FROM
ist ein T-SQL-Erweiterung zum SQL-standardDELETE
bietet eine alternative zur Verwendung einer Unterabfrage. Aus der Hilfe:Würden Sie wollen, in Ihrem zweiten Lösung, so etwas wie
-- ungetestet!
LÖSCHEN VON
dbo.SubProtocols -- ProtocolHeaders, etc
AUS
dbo.SubProtocols
INNER JOIN @Protokolle AUF SubProtocols.ProtocolID = @Protokolle.ProtocolID
Aber!!
Ist es nicht möglich, ändern Sie Ihre design, so dass alle susidiary Protokoll-Tabellen ein
FOREIGN KEY
mitDELETE CASCADE
zu den wichtigstenProtocols
Tabelle? Dann könnten Sie einfachDELETE
ausProtocols
und den rest kümmern würde...Bearbeiten hinzufügen:
Wenn Sie bereits
FOREIGN KEY
s einrichten, müssen Sie die Verwendung der DDL, um Sie zu ändern (ich denke, dass ein löschen und neu zu erstellen benötigt wird), um für Sie zu habenDELETE CASCADE
eingeschaltet. Sobald dieser eingerichtet ist, wird einDELETE
aus der Haupttabelle automatischDELETE
verwandten Datensätzen in der untergeordneten Tabelle.FOREIGN KEY
sDELETE CASCADE
wäre der beste Weg, denke ich.Ohne die temp-Tabelle, riskieren Sie löschen unterschiedliche Zeilen in der zweiten löschen, aber das dauert drei Operationen zu tun.
Könnte man löschen aus der ersten Tabelle, und verwenden Sie die AUSGABE IN Klausel einfügen, in eine temp-Tabelle, alle IDs und verwenden Sie dann die temp-Tabelle löschen der zweiten Tabelle. Dies wird sicherstellen, dass Sie nur löschen Sie die entsprechenden Tasten, mit und mit nur zwei Anweisungen.
WÄHLEN SIE AUSGABE:
(3 Zeile(N) betroffen)