Auswirkungen auf Einzel-und mehrere Zeilen
Sie müssen sich bewusst sein, vor allem, dass in einigen Datenbank-Produkten, wie SQL Server 2000, ein Trigger ausgelöst wird einmal für jede Aussage und nicht nur einmal für jede Zeile durch eine Anweisung betroffen. Wir können Ihnen nicht sagen, wie oft haben wir gesehen, Entwickler machen kritische Fehler-Codierung auf dem sehr falschen Annahme, dass die Trigger-Code ausgeführt wird einmal für jede Zeile von der Anweisung nicht nur einmal für die gesamte Aussage beeinträchtigt wird. Auch Oracle, die können Sie Trigger definieren, dass das Feuer einmal für jede Zeile durch eine Anweisung betroffen, können immer noch Probleme bei der Bearbeitung Daten korrekt, wie man später sehen. Sie haben mehrere Möglichkeiten, um dieses Problem in SQL Server 2000. Die folgenden Teile einen Blick auf diese Abhilfen. Wenn Ihre Anwendung ist so ausgelegt, dass Sie nie mehr als eine einzelne Zeile in einer Zeit, in eine Tabelle einfügen, können Sie platzieren, eine Beschränkung auf die Tabelle in diesem Sinne, indem Sie den Code, um seine INSERT-Trigger. IF (@ @ ROWCOUNT! = 1) BEGIN RAISERROR 50010 "Du kannst nicht geben mehr als eine Zeile zu einer Zeit." ROLLBACK TRANSACTION RETURN END CREATE TRIGGER tU_OrderItem ON OrderItem NACH Update AS BEGIN / * Deklariert Variablen für die Verwendung durch den Trigger * / DECLARE @ iOldQuantity INTEGER, INTEGER iNewQuantity @ @ sOldItemNumber VARCHAR (15), @ sNewItemNumber VARCHAR (15) / * Holen Sie sich die alten bestellte Menge und Ziffer * / SELECT @ iOldQuantity = Menge, @ sOldItemNumber = ItemNumber AUS entfällt / * der neue bestellte Menge und Ziffer * / SELECT @ iNewQuantity = Menge, @ Get sNewItemNumber = ItemNumber aus eingefügten / * Update der alten Position, um den ehemaligen bestellte Menge wieder in den Bestand * / UPDATE InventoryItem SET AvailableToSell put = AvailableToSell + @ iOldQuantity WHERE ItemNumber = @ sOldItemNumber / * Update der neuen Artikel-Nummer (es kann sich geändert haben) zu Nehmen Sie die neue bestellte Menge aus dem Inventar * / UPDATE InventoryItem SET AvailableToSell = AvailableToSell - @ iOldQuantity WHERE ItemNumber = @ sNewItemNumber END Diese Trigger-Code ausgeführt wird nur einmal verwendet und nur die Werte aus der ersten Reihe in der pseudotable entfällt, bei der Verursachung nur eine Zeile in der Tabelle InventoryItem wiederum aktualisiert werden. Stellen Sie sich das Nest Code. CREATE TRIGGER tU_OrderItem ON OrderItem Nach Update AS BEGIN / * die alte bestellte Menge wieder in den Bestand * / UPDATE InventoryItem SET AvailableToSell Put = AvailableToSell + d.Quantity AUS entfällt d INNER JOIN InventoryItem ii ON d.ItemNumber = ii.ItemNumber / * Nehmen Sie die neue bestellte Menge aus dem Inventar Denken Sie daran: die Artikelnummer kann sich geändert haben! * / UPDATE InventoryItem SET AvailableToSell = AvailableToSell - i.Quantity aus eingefügten i INNER JOIN InventoryItem ii ON i.ItemNumber = ii.ItemNumber END Diese Trigger-Code aktualisiert alle InventoryItem Zeilen entsprechen den OrderItem Zeilen, die aktualisiert, auch wenn die wichtigsten Änderungen ItemNumber Wert. Durch den Beitritt zum eingefügt und gelöscht Pseudotabellen mit dem InventoryItem Tabelle können Sie die notwendigen Berechnungen durchführen zu steigern und jeden Gegenstand des Inventars Abnahme durch den alten und neuen bestellten Mengen, respectively. Der Code ist auch viel weniger umständlich geschrieben, wenn es richtig. In der Praxis würden Sie wahrscheinlich drei Dinge anders. Erstens, Sie hätten drei verschiedene Trigger, um diese Aufgabe zu erreichen-ein jeder für die INSERT, UPDATE und DELETE-Ereignisse und jeder würde die Logik für die Anpassung der Lagerbestand entsprechend der Datenbank-Ereignis, das eingetreten enthalten. Zweitens, würden Sie Logik in Ihrem UPDATE-Trigger Ort, um zu verhindern Änderung der ItemNumber von seinem ursprünglichen Wert. Drittens würden Sie die beiden UPDATE Abfragen in der Trigger in einer Abfrage zu konsolidieren Beitritt zur InventoryItem Tisch und beide Pseudotabellen, wie in den Code. CREATE TRIGGER tU_OrderItem ON OrderItem NACH Update AS BEGIN IF (UPDATE (ItemNumber)) BEGIN RAISERROR 50010 "Sie können nicht die Artikel-Nr." ROLLBACK TRANSACTION RETURN END UPDATE InventoryItem SET AvailableToSell = ii.AvailableToSell + d.Quantity - i.Quantity aus eingefügten i INNER JOIN InventoryItem ii ON i.ItemNumber = ii.ItemNumber INNER JOIN entfällt d ON d.ItemNumber = ii.ItemNumber END Stellen Sie sich vor Abrufen von ein paar Zeilen in einem separaten Platz im Speicher und dann holen diese Zeilen ein zu einer Zeit, Blick auf die Werte in der Spalte jeder Zeile und möglicherweise auch eine Operation auf der Grundlage der Werte in jeder Zeile. Das ist das Leben eines Cursors. Cursors sind ein letztes Mittel, weil sie schwerfällig, langsam und ressourcen-intensiv, und sie zerstören die Skalierbarkeit der Datenbank, wenn sie auf hoher Durchsatz von Transaktionen Bereiche Ihrer Datenbank verwendet. Cursors sind oft dort eingesetzt, wo sie nicht sein sollte, entweder als Ersatz für eine gute SQL-Code oder zu umgehen, schlecht konzipierte Datenbanken. Manchmal ist jedoch ein Cursor die einzig praktikable Lösung für Ihr Problem. Nehmen wir zum Beispiel, dass Sie eine gespeicherte Prozedur namens sp_ArchiveCall, dass in vielen Orten in Ihrer Datenbank, einschließlich der Insert-Trigger in den gezeigten Code verwendet wird. CREATE PROCEDURE sp_ArchiveCall (@ SupportCallID Integer) AS BEGIN UPDATE SupportCall SET Status = 60 WHERE SupportCallID = @ SupportCallID END GO CREATE TRIGGER tI_SupportCallArchive ON SupportCallArchive AFTER INSERT AS BEGIN DECLARE @ SupportCallID Integer curClosedCalls DECLARE CURSOR FOR SELECT SupportCallID aus eingefügten OPEN curClosedCalls FETCH NEXT FROM curClosedCalls INTO @ SupportCallID WHILE @ @ FETCH_STATUS = 0 BEGIN EXECUTE sp_ArchiveCall @ SupportCallID FETCH NEXT FROM curClosedCalls INTO @ SupportCallID END CLOSE curClosedCalls DEALLOCATE curClosedCalls END gehen Sie verwenden einen Cursor hier, weil Sie die gespeicherte Prozedur muss einmal für jede Zeile von der Anweisung betroffen nennen, und der einzige Weg, dies zu tun ist, um die gespeicherte Prozedur-Aufruf innerhalb jeder Abruf Ort oder holen eines Cursors Reihe. Bitte behandeln Sie alle Cursor mit Angst und Abscheu. Sie sind schlecht, und Sie lieber eine vertretbare Entschuldigung für ihre Verwendung oder Ihre Source-Code "Peer Review" ist irreführend, wenn sie schrecklich Verlegenheit zu bringen. Ein Artikel eingereicht von Samuel Wardy Disclaimer:Unsere Website ist nicht verantwortlich für den Inhalt dieses Artikels. Webarticles ist eine kostenlose Informationsquelle. Wichtig: Dieser Artikel "Affecting Einzel-und mehrere Zeilen" wurde durch ein automatisches Software übersetzt. Wir fühlen uns leid für alle Rechtschreibfehler, die möglicherweise aufgetreten sind. Vielen Dank für Ihr Verständnis.
|
|||||
| Online: 131 users browsing the articles directory |
|
|