Câu trả lời:
Có, có thể xác định mã đang chạy, bằng cách sử dụng chức năng hệ thống @@ Procid và OBRI_NAME tốt hơn (@@ PROCID) để có tên đầy đủ.
Định nghĩa: "Trả về mã định danh đối tượng (ID) của mô-đun Transact-SQL hiện tại. Mô-đun Transact-SQL có thể là một thủ tục được lưu trữ, hàm do người dùng xác định hoặc kích hoạt. @@ PROCID không thể được chỉ định trong các mô-đun CLR hoặc trong- nhà cung cấp truy cập dữ liệu. "
Bạn có thể đọc về nó ở đây .
Một lựa chọn khác là kiểm tra kế hoạch sql của spid hiện tại và lưu thông tin đó vào bảng ghi nhật ký. Một truy vấn mẫu được sử dụng trong mỗi quy trình để lưu dữ liệu kiểm toán sẽ là:
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
Có thể có quá nhiều chi tiết ở đó..nhưng tôi tin rằng bạn có ý tưởng.
Một lựa chọn thứ ba sẽ được sử dụng context_info thông tin đến phiên SP hiện tại của. Và liên kết ở đâu đó thông tin bối cảnh được lưu ở đó với mỗi thủ tục. Ví dụ trong thủ tục1 bạn viết 111 vào ngữ cảnh, trong thủ tục2 bạn viết 222 .. và cứ thế.
Nhiều thông tin hơn về bối cảnh_info bạn có thể đọc trong câu hỏi SO này .
OBJECT_NAME(@@PROCID)
trả về tên kích hoạt, không phải là cuộc gọi Proc.
Tôi cũng muốn làm điều này. Cảm ơn câu trả lời. Vì tôi vẫn ở đây, tôi sẽ đăng bài kiểm tra của mình để tiết kiệm thời gian cho người khác :)
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
XE cung cấp một cách khác để biết đến ngăn xếp T-SQL mặc dù SQL Server 2008 có thể không hỗ trợ loại sự kiện đã sử dụng. Giải pháp bao gồm kích hoạt, lỗi và phiên XEvent. Tôi lấy ví dụ của Jim Brown để chỉ ra cách nó hoạt động.
Trước hết, tôi đã thử nghiệm giải pháp cho SQL Server 2016 SP2CU2 Dev Edition. SQL Server 2008 hỗ trợ một số EXevent, nhưng tôi không có trường hợp nào để tôi không thể kiểm tra nó.
Ý tưởng là tạo ra lỗi người dùng trong khối thử bắt giả, sau đó bắt lỗi trong phiên XEvent bằng tsql_stack
hành động. SQLSERVER.error_reported
Loại XEvent có thể bắt tất cả các lỗi ngay cả khi một khối thử bắt bẫy chúng. Cuối cùng, sys.dm_exec_sql_text
trích xuất các truy vấn T-SQL từ truy vấn xử lý tsql_stack
hành động nào đưa ra.
Một ví dụ từ câu trả lời của Jim Brown, mà tôi đã phát triển, được hiển thị bên dưới. Một kích hoạt làm tăng lỗi với văn bản 'bắt tôi'. Phiên XEvent bắt lỗi chỉ với văn bản như 'bắt tôi'.
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
Bây giờ, nếu bạn khởi chạy phiên XEvent (SSMS, Object Explorer, Management, Extended Events, Sairs, Catch_inserts_into_Test), hãy thực thi usp_RootProcIDTest và xem bộ đệm vòng của phiên XEvent, bạn sẽ thấy XML bao gồm nút <action name="tsql_stack" package="sqlserver">
. Có một chuỗi các nút khung. Đặt các giá trị của handle
thuộc tính 's vào hàm hệ thống' sys.dm_exec_sql bản 'và 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);
XEvent cho phép bạn làm nhiều hơn thế này! Đừng bỏ lỡ cơ hội để tìm hiểu chúng!