Antworten:
Ja, es ist möglich, den laufenden Code mithilfe der Systemfunktion @@ procid zu identifizieren und besser OBJECT_NAME (@@ PROCID), um den vollständigen Namen zu erhalten.
Definition: Gibt die Objektkennung (ID) des aktuellen Transact-SQL-Moduls zurück. Ein Transact-SQL-Modul kann eine gespeicherte Prozedur, eine benutzerdefinierte Funktion oder ein Trigger sein. Datenzugriffsprovider verarbeiten. "
Sie können darüber lesen Sie hier .
Eine andere Möglichkeit wäre, den SQL-Plan der aktuellen Spid zu überprüfen und diese Informationen in einer Protokollierungstabelle zu speichern. Eine Beispielabfrage, die in jedem Verfahren zum Speichern von Überwachungsdaten verwendet wird, lautet:
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 auf die Idee kommen.
Eine dritte Möglichkeit wäre, die context_info- Informationen für die aktuelle SP-Sitzung zu verwenden. Und verknüpfen Sie die dort gespeicherten Kontextinformationen mit jeder Prozedur. In procedure1 schreiben Sie beispielsweise 111 in den Kontext, in procedure2 schreiben Sie 222 .. und so weiter.
Weitere Informationen zu context_info finden Sie in dieser SO-Frage .
OBJECT_NAME(@@PROCID)
der Triggername zurückgegeben, nicht der aufrufende Prozess.
Ich wollte das auch tun. Danke für die Antwort. Da ich immer noch hier bin, werde ich meinen Test posten, um anderen 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 weitere Möglichkeit, einen T-SQL-Stapel zu ermitteln, obwohl SQL Server 2008 einen verwendeten Ereignistyp möglicherweise nicht unterstützt. Die Lösung besteht aus einem Trigger, einem Fehler und einer XEvent-Sitzung. Ich habe Jim Browns Beispiel genommen, 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, so dass ich es nicht testen konnte.
Die Idee ist, einen Benutzerfehler in einem Dummy-Try-Catch-Block zu generieren und den Fehler dann in einer XEvent-Sitzung mit tsql_stack
action abzufangen . SQLSERVER.error_reported
Der XEvent-Typ kann alle Fehler abfangen, obwohl sie von einem Try-Catch-Block abgefangen werden. Am Ende sys.dm_exec_sql_text
extrahieren Sie T-SQL-Abfragen aus den Abfrage-Handles, die die tsql_stack
Aktion gibt.
Ein Beispiel aus der Antwort von Jim Brown, die ich entwickelt habe, ist unten dargestellt. Ein Trigger löst den Fehler mit dem Text 'catch me' aus. Die XEvent-Sitzung fängt Fehler nur mit dem Text 'catch me' ab.
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 nun die XEvent-Sitzung starten (SSMS, Objekt-Explorer, Verwaltung, Erweiterte Ereignisse, Sitzungen, catch_insertion_into_Test), usp_RootProcIDTest ausführen und den Ringpuffer der XEvent-Sitzung prüfen, sollte das XML angezeigt werden, aus dem der Knoten besteht <action name="tsql_stack" package="sqlserver">
. Es gibt eine Folge von Rahmenknoten. handle
Fügen Sie die Werte des Attributs von a in die Systemfunktion 'sys.dm_exec_sql_text' ein und gehen Sie wie folgt vor:
-- 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);
Mit XEvent können Sie noch viel mehr tun! Verpassen Sie nicht die Gelegenheit, sie zu lernen!