Frage

Ich habe 10 gespeicherte Verfahren und jeder von ihnen führt in ein Tischxtex ein.

Ist es in einem Auslöserkörper von Tablex möglich, das zu erhalten, was Objekt zu einer Änderung des Tabellenxpaszes (gespeicherter Proc1 oder SP2 oder ...) verursacht?

Vielen Dank.

War es hilfreich?

Lösung

Ja, es ist möglich, den laufenden Code zu identifizieren, von Verwenden der Funktion @@ Procid System, und besser Object_Name (@@ Procid), um den vollständigen Namen zu haben.

Definition: "Gibt die Objektkennung (ID) des aktuellen Transact-SQL-Moduls zurück. Ein Transact-SQL-Modul kann eine gespeicherte Prozedur, eine benutzerdefinierte Funktion oder Trigger sein. @@ Procid kann nicht in CLR-Modulen oder in der In- Verarbeitungsdatenzugriffsanbieter. "

Sie können darüber lesen hier.

Eine andere Option wäre zu Überprüfen Sie den SQL -Plan des aktuellen Spids und speichern Sie diese Informationen in einer Protokollierungstabelle. Eine Beispielabfrage, die in jedem Verfahren zum Speichern von Prüfungsdaten verwendet werden soll, wäre:

select sp.hostname, sp.program_name, sp.loginame,
    st.text as query_text
from sysprocesses sp
cross apply sys.dm_exec_sql_text(sp.sql_handle) as st  
where sp.spid = @@spid

Vielleicht gibt es dort zu viele Details ... aber ich glaube, dass Sie die Idee haben.

Eine dritte Option wäre zu Verwenden Sie das context_info Information zur aktuellen SP -Sitzung. Und assoziieren Sie irgendwo die mit jeder Prozedur gespeicherten Kontextinformationen. In der Prozedur1 schreiben Sie beispielsweise 111 in den Kontext, in Prozedure2 Sie schreiben 222 .. und so weiter.

Viel mehr Informationen zu context_info, in denen Sie lesen können Diese Frage.

Andere Tipps

Ich wollte das auch tun. Danke für die Antwort. Da ich noch hier bin, werde ich meinen Test veröffentlichen, um andere Zeit zu sparen :)

CREATE TABLE  Test ( TestID INT )
GO

CREATE TRIGGER TestTrigger ON Test
FOR INSERT
AS

SELECT CAST(CONTEXT_INFO() AS NVARCHAR(128));
GO

CREATE PROCEDURE usp_ProcIDTest
AS

DECLARE @ProcedureName VARBINARY(MAX) = CAST(OBJECT_NAME(@@PROCID) AS VARBINARY(MAX))
SET CONTEXT_INFO @ProcedureName

INSERT INTO Test ( TestID ) VALUES ( 1 ) 

GO

EXEC usp_ProcIDTest
GO

DROP TABLE Test
GO

Xevents bieten eine andere Möglichkeit, einen T-SQL-Stack bekannt zu machen, obwohl SQL Server 2008 einen gebrauchten Ereignisart möglicherweise nicht unterstützt. Die Lösung besteht aus einem Auslöser, einem Fehler und einer Xevent -Sitzung. Ich nahm Jim Browns Beispiel, um zu zeigen, wie es funktioniert.

Zunächst habe ich die Lösung für SQL Server 2016 SP2CU2 Dev Edition getestet. SQL Server 2008 unterstützt einige exevent, aber ich habe keine Instanz, damit ich es nicht testen konnte.

Die Idee besteht tsql_stack Aktion. SQLSERVER.error_reported XEvent-Typ kann alle Fehler aufnehmen, obwohl ein Try-Catch-Block sie fängt. Schlussendlich, sys.dm_exec_sql_text Extrahieren Sie T-SQL-Abfragen aus den Abfragetreifen, die tsql_stack Aktion gibt.

Ein Beispiel aus Jim Browns Antwort, die ich entwickelt habe, ist unten gezeigt. Ein Auslöser erhöht den Fehler mit dem Text 'Catch Me'. Die Xevent -Sitzung fängt Fehler nur mit dem Text wie 'Catch Me' auf.

CREATE TABLE  Test ( TestID INT )

GO

CREATE TRIGGER TestTrigger ON Test
FOR INSERT
AS
BEGIN TRY
    SET XACT_ABORT OFF; -- REALLY IMPORTANT!
    /* make an catching a great deal more interesting */
    DECLARE @TestID NVARCHAR(MAX) ;
    SELECT TOP (1) @TestID = CAST(ins.TestID AS NVARCHAR(MAX)) FROM inserted AS ins ;
    RAISERROR (N'catch_me TestID = "%s"' , 11 , 0 , @TestID) ;
END TRY BEGIN CATCH /* NOTHING TO DO */ END CATCH

GO

CREATE PROCEDURE usp_ProcIDTest
AS
INSERT INTO Test ( TestID ) VALUES ( 1 ) 

GO

CREATE PROCEDURE usp_RootProcIDTest
AS
EXEC usp_ProcIDTest

GO

-- This XEvent session definition was kindly provided by XEvent 'New Session' wizard.
CREATE EVENT SESSION [catch_insertion_into_Test] ON SERVER 
ADD EVENT sqlserver.error_reported(
    ACTION(package0.callstack,sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.client_pid,sqlserver.database_id,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack,sqlserver.username,sqlserver.context_info,sqlserver.plan_handle)
    WHERE ([message] like N'catch_me%'))
ADD TARGET package0.ring_buffer(SET max_memory=(10240))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=ON)

GO

Wenn Sie die XEvent -Sitzung (SSMS, Object Explorer, Management, erweiterte Ereignisse, Sitzungen, Catch_insertion_into_test) starten, führen Sie USP_ROOTPROCIDTEST aus und sehen <action name="tsql_stack" package="sqlserver">. Es gibt eine Abfolge von Rahmenknoten. Setzen Sie die Werte von a handle's Attribut in die Systemfunktion' sys.dm_exec_sql_text 'und voilà:

-- REPLACE MY HANDLES WITH YOURS
SELECT * FROM sys.dm_exec_sql_text(0x03000800D153096910272C01A6AA000000000000000000000000000000000000000000000000000000000000);
SELECT * FROM sys.dm_exec_sql_text(0x030008000A78FD6912272C01A6AA000001000000000000000000000000000000000000000000000000000000);
SELECT * FROM sys.dm_exec_sql_text(0x03000800439CF16A13272C01A6AA000001000000000000000000000000000000000000000000000000000000);

An execution call stack example

Xevent lässt Sie viel mehr als das tun! Verpassen Sie nicht die Möglichkeit, sie zu lernen!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top