Gibt es eine Möglichkeit, einen SQL Server-Trigger nur für einen bestimmten Bereich der Ausführung zu deaktivieren?

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

  •  05-07-2019
  •  | 
  •  

Frage

In SQL Server 2005 gibt es eine Möglichkeit für einen Auslöser, um herauszufinden, was Objekt zum Brennen von dem Auslöser verantwortlich? Ich möchte diese verwenden, um den Auslöser für eine gespeicherte prodecure zu deaktivieren.

Gibt es eine andere Möglichkeit, den Auslöser nur für die aktuelle Transaktion zu deaktivieren? Ich kann den folgenden Code verwenden, aber wenn ich mich nicht irre, wäre es gleichzeitig ablaufenden Transaktionen als auch beeinflussen -., Die eine schlechte Sache sein würde

DISABLE TRIGGER { [ schema_name . ] trigger_name [ ,...n ] | ALL } ON { object_name | DATABASE | ALL SERVER } [ ; ]

ENABLE TRIGGER { [ schema_name . ] trigger_name [ ,...n ] | ALL } ON { object_name | DATABASE | ALL SERVER } [ ; ]

Wenn möglich, möchte ich die Technik der mit einem „NoTrigger“ Feld in meinem Tisch zu vermeiden und eine NoTrigger = null tun, weil ich den Tisch so klein wie möglich halten möchten.

Der Grund Ich mag würde, den Auslöser zu vermeiden, weil es Logik enthält, die für die manuellen Aktualisierungen der Tabelle wichtig ist, aber meine gespeicherte Prozedur wird diese Logik kümmern. Da dies ein sehr verwendetes Verfahren sein, ich will es schnell sein.

  

Trigger verhängen zusätzlichen Aufwand auf dem Server, weil sie eine implizite Transaktion initiieren. Sobald ein Trigger ausgeführt wird, wird eine neue implizite Transaktion gestartet wird, und jede Datenabfrage innerhalb einer Transaktion wird Sperren auf dem betroffenen Tabellen halten.

Von: http://searchsqlserver.techtarget.com/ tip / 1,289483, sid87_gci1170220,00.html # Trigger

War es hilfreich?

Lösung

Ich habe gerade gesehen, dieser Artikel vor kurzem auf dem SQL-Server-Zentral Newsletter hervorgehoben und es erscheint eine Möglichkeit zu bieten, die Sie nützlich finden können die CONTEXT_INFO auf der Verbindung mit:

http://www.mssqltips.com/tip.asp?tip=1591


EDIT von Terrapin:

Der obige Link enthält den folgenden Code:

USE AdventureWorks;  
GO  
-- creating the table in AdventureWorks database  
IF OBJECT_ID('dbo.Table1') IS NOT NULL  
DROP TABLE dbo.Table1  
GO  
CREATE TABLE dbo.Table1(ID INT)  
GO   
-- Creating a trigger  
CREATE TRIGGER TR_Test ON dbo.Table1 FOR INSERT,UPDATE,DELETE  
AS  
DECLARE @Cinfo VARBINARY(128)  
SELECT @Cinfo = Context_Info()  
IF @Cinfo = 0x55555  
RETURN  
PRINT 'Trigger Executed'  
-- Actual code goes here  
-- For simplicity, I did not include any code  
GO  

Wenn Sie den Auslöser, um zu verhindern ausgeführt werden Sie folgendes tun:

SET Context_Info 0x55555 
INSERT dbo.Table1 VALUES(100)

Andere Tipps

Wenn Ihr Auslöser verursacht Leistungsprobleme in der Anwendung, dann ist der beste Ansatz ist, alle manuellen Aktualisierungen der Tabelle zu entfernen, und alle Aktualisierungen erfordern durch die insert / update gespeicherte Prozeduren zu gehen, die die richtige Update-Logik enthalten. Dann können Sie den Auslöser vollständig entfernen.

Ich schlage vor, zu leugnen Tabellenaktualisierungsberechtigungen, wenn sonst nichts funktioniert.

Dies löst auch das Problem des doppelten Code. Duplizierung Code in dem Update-SP und den Auslöser ist eine Verletzung der guten Software-Engineering-Prinzipien und ein Wartungsproblem sein.

TABLE Tabl DISABLE TRIGGER trg ALTER

http://doc.ddart.net/mssql/sql70/aa -az_5.htm

Ich verstehe nicht, die Bedeutung Ihres ersten Absatzes obwohl

Da Sie zeigen, dass die Triggerlogik enthält alle Updates zu handhaben, auch manuelle Updates, sein, dass sollte dann, wenn die logische befindet. Das Beispiel, das Sie erwähnen, bei dem eine gespeicherte Prozedur „Pflege dieser Logik nehmen“ bedeutet doppelten Code. Außerdem, wenn Sie sicher sein wollen, dass jede UPDATE-Anweisung Mit dieser Logik unabhängig vom Autor angewandt hat, dann ist der Auslöser der richtige Ort für sie. Was passiert, wenn ein Verfahren jemand Autoren aber vergisst die Logik noch einmal zu duplizieren? Was passiert, wenn es Zeit ist, um die Logik zu ändern?

Nicht sicher, ob dies eine gute Idee ist, aber es scheint, für mich zu arbeiten. Transaktion sollte Einfügungen in die Tabelle von anderen Prozessen verhindern, während Trigger deaktiviert ist.

IF OBJECT_ID('dbo.TriggerTest') IS NOT NULL
 DROP PROCEDURE dbo.TriggerTest
GO

CREATE PROCEDURE [dbo].[TriggerTest]
AS
BEGIN TRANSACTION trnInsertTable1s
;
DISABLE TRIGGER trg_tblTable1_IU ON tblTable1
;
BEGIN -- Procedure Code
    PRINT '@@trancount'
    PRINT @@TRANCOUNT
    -- Do Stuff

END -- Procedure Code
;
ENABLE TRIGGER trg_tblTable1_IU ON tblTable1

IF @@ERROR <> 0 ROLLBACK TRANSACTION
ELSE COMMIT TRANSACTION

Sie den Auslöser nicht deaktivieren. Sie sind richtig, dass für jede gleichzeitige Transaktionen deaktivieren wird.

Warum wollen Sie den Auslöser deaktivieren? Was tut es? Warum ist casuing der Auslöser ein Problem? Es ist in der Regel eine schlechte Idee, eine Tigger aus einer Datenintegrität Perspektive zu deaktivieren.

Betrachten Sie den Auslöser Schreiben zu verbessern, wenn die Leistung das Problem ist.

waffled ich ein bisschen auf diesen. Auf der einen Seite bin ich sehr anti-Auslöser vor allem, weil es ein weiterer Platz für mich, für Code zu suchen Ausführung gegen meinen Tisch, zusätzlich zu den in dem Artikel genannten Gründen in der Frage Post verknüpft.

Auf der anderen Seite, wenn Sie Logik stabil und unveränderlich Geschäftsregeln oder Kreuztisch Aktionen durchzusetzen (wie eine History-Tabelle beibehalten), dann wäre es sicherer, das in einen Auslöser zu bekommen, so Prozedur Autoren und Programmierer nicht tun müssen damit umgehen - es funktioniert einfach.

Also, meine Empfehlung ist, die notwendige Logik in den Trigger zu setzen, anstatt in diesem proc, die zwangsläufig zu mehreren Procs mit derselben Befreiung wachsen.

Ich konfrontierte gerade das gleiche Problem und kam mit der folgenden Lösung auf, was für mich funktioniert.

  1. Erstellen Sie eine permanente DB-Tabelle, die einen Datensatz für jeden Trigger enthält, die Sie (z refTriggerManager) deaktiviert werden soll; Jede Zeile enthält die Triggernamen (z.B. strTriggerName = 'MyTrigger') und ein Bit-Flags (z.B. blnDisabled, default auf 0).

  2. Zu Beginn des Abzugs Körper, aufblicken strTriggerName = 'MyTrigger' in refTriggerManager. Wenn blnDisabled = 1, dann zurück, ohne den Rest des Trigger-Code ausgeführt wird, sonst den Trigger-Code bis zum Abschluss fortzusetzen.

  3. In der gespeicherten proc, in dem Sie den Auslöser deaktivieren möchten, gehen Sie wie folgt vor:


BEGIN TRANSACTION

UPDATE refTriggerManager SET blnDisabled = 1 WHERE strTriggerName = 'MyTrigger'

/ * die Tabelle aktualisieren, die besitzt ‚MyTrigger,‘ die man aber deaktiviert werden soll. Da refTriggerManager.blnDisabled = 1, 'MyTrigger' zurückkehrt, ohne seinen Code ausführt. * /

UPDATE refTriggerManager SET blnDisabled = 0 WHERE triggerName = 'MyTrigger'

/ * Optional UPDATE-Code, der Trigger auslöst. Da refTriggerManager.blnDisabled = 0, führt 'MyTrigger' in vollem Umfang. * /

COMMIT TRANSACTION


All dies geschieht innerhalb einer Transaktion, so wird es von der Außenwelt isoliert und wird nicht anderes Updates auf dem Zieltabelle beeinflussen.

Sieht jemand irgendein Problem mit diesem Ansatz?

Bill

ich mit einigen anderen Antworten stimmen. Sie nicht den Auslöser deaktivieren.

Das ist reine Meinung, aber ich vermeiden Auslöser wie die Pest. Ich habe nur sehr wenige Fälle gefunden, wo ein Trigger verwendet wurde Datenbank-Regeln zu erzwingen. Es gibt offensichtliche Grenzfälle in meiner Erfahrung, und ich habe nur meine Erfahrungen, auf die diese Aussage zu machen. Ich habe normalerweise Trigger verwendeten einzufügen einige relationalen Daten zu sehen (die von der Geschäftslogik durchgeführt werden sollen), zum Einfügen von Daten in Berichtstabelle dh die Daten Denormalisierung (die mit einem Prozess außerhalb der Transaktion durchgeführt werden kann), oder die Daten für die Transformation irgendwie.

Es gibt legitime Anwendungen für Trigger, aber ich denke, dass im täglichen Geschäft Programmierung sie sind dünn gesät. Dies kann in Ihrem aktuellen Problem nicht helfen, aber Sie könnten erwägen den Auslöser komplett zu entfernen und erreicht die Arbeit der Auslöser in einer anderen Art und Weise zu tun.

können Sie ' Exec ' Funktion deaktivieren und Trigger aus einer gespeicherten Prozedur zu aktivieren. Beispiel: EXEC ('ENABLE TRIGGER dbo.TriggerName on dbo.TriggeredTable')

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top