ট্রিগারটিতে কার্যকর করা কল স্ট্যাক পাওয়া কি সম্ভব?


16

আমার কাছে 10 টি সঞ্চিত পদ্ধতি রয়েছে এবং তাদের প্রত্যেকেরই একটি টেবিলএক্সে INSERT করা হয়।

টেবিলএক্সের কোনও ট্রিগার বডিতে কি বস্তু টেবিলএক্সের পরিবর্তিত কারণ হতে পারে (সঞ্চিত প্রো 1 বা এসপি 2 বা ....)?

ধন্যবাদ.

উত্তর:


9

হ্যাঁ, @@ প্রোসিড সিস্টেম ফাংশনটি ব্যবহার করে চলমান কোডটি সনাক্ত করা এবং পুরো নাম রাখার জন্য আরও ভাল ওবিজেইসিএআইএলএর (@@ প্রোসিআইডি) সনাক্ত করা সম্ভব।

সংজ্ঞা: "বর্তমান লেনদেন-এসকিউএল মডিউলটির অবজেক্ট আইডেন্টিফায়ার (আইডি) প্রদান করে A প্রক্রিয়া ডেটা অ্যাক্সেস প্রদানকারী ""

আপনি এটি সম্পর্কে এখানে পড়তে পারেন ।

আর একটি বিকল্প হ'ল বর্তমান স্পিডের স্ক্যুয়াল পরিকল্পনাটি পরীক্ষা করে লগিং টেবিলে সেই তথ্যটি সংরক্ষণ করা। নিরীক্ষণের তথ্য সংরক্ষণের জন্য প্রতিটি পদ্ধতিতে ব্যবহৃত একটি নমুনা ক্যোয়ারী হ'ল:

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

সম্ভবত সেখানে অনেকগুলি বিবরণ রয়েছে..কিন্তু আমি বিশ্বাস করি যে আপনি ধারণাটি পেয়েছেন।

তৃতীয় বিকল্পটি হ'ল বর্তমান এসপির সেশনে কনটেক্সট_ইনফো তথ্য ব্যবহার করা । এবং প্রতিটি পদ্ধতির সাথে সেখানে সংরক্ষিত প্রসঙ্গের তথ্য কোথাও যুক্ত করুন। পদ্ধতি 1 তে উদাহরণস্বরূপ আপনি 111 প্রসঙ্গে লিখুন, পদ্ধতি 2 তে আপনি 222 লিখেন .. এবং আরও।

প্রসঙ্গ_ইনফো সম্পর্কিত আরও অনেক তথ্য আপনি এই এই প্রশ্নটিতে পড়তে পারেন ।


1
1) ট্রিবিতে ওবিজেইসিআইএল (@@ প্রোসিআইডি) ট্রিগার নামটি দেয় :( 2) কেবল ট্রিগারটিতে তথ্য থাকা প্রয়োজন। 3) প্রসঙ্গ_ ইনফো একটি সমাধান। ধন্যবাদ।
গারিক

1
হ্যাঁ, ট্রিগারটির ভিতরে OBJECT_NAME(@@PROCID)ট্রিগার নামটি ফিরে আসে, কলিং প্রোকে না।
অধ্যাপক

এটি কেবল সাধারণ ভুল। এটি ট্রিগারটির নাম ফিরিয়ে দেয়, ওপি যেমনটি বলেছিল তেমন কলিং পদ্ধতির নয়
বিপরীত প্রকৌশলী

একমত, উত্তর ভুল। আপনি যদি প্রবাহের প্রক্রিয়াটি পরিবর্তন করতে পারেন তবে CONTEXT_INFO কাজ করে।
টম ওয়ারফিল্ড

3

আমিও এটি করতে চেয়েছিলাম উত্তরের জন্য ধন্যবাদ. আমি যেমন এখানে আছি, অন্যের সময় বাঁচাতে আমার পরীক্ষা পোস্ট করব :)

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

2

এক্সএভেন্টস টি-এসকিউএল স্ট্যাক পরিচিত হওয়ার জন্য অন্য উপায় সরবরাহ করে যদিও এসকিউএল সার্ভার ২০০৮ সম্ভবত ব্যবহৃত ইভেন্টের ধরণটি সমর্থন করে না। সমাধানটিতে একটি ট্রিগার, একটি ত্রুটি এবং এক্সএভেন্ট সেশন থাকে। জিম ব্রাউন এর উদাহরণটি নিয়েছে যেভাবে এটি কাজ করে show

প্রথমত, আমি এসকিউএল সার্ভার 2016 এসপি 2 সিই 2 দেব সংস্করণে সমাধানটি পরীক্ষা করেছিলাম। এসকিউএল সার্ভার ২০০৮ কিছু এক্সাইভেন্টকে সমর্থন করে তবে আমার এটির কোনও উদাহরণ নেই যাতে আমি এটি পরীক্ষা করতে পারি না।

ধারণাটি হ'ল ডামি ট্রাই-ক্যাচ ব্লকে কোনও ব্যবহারকারীর ত্রুটি উত্পন্ন করা হবে, তারপরে এক্সএভেন্ট সেশনের ভিতরে tsql_stackক্রিয়া সহ ত্রুটিটি ধরা । SQLSERVER.error_reportedএক্সএভেন্ট টাইপ সমস্ত ত্রুটিগুলি ধরতে পারে যদিও চেষ্টা-ধরা ব্লক তাদের আটকে দেয়। শেষ পর্যন্ত, sys.dm_exec_sql_textকোয়েরি থেকে টি-এসকিউএল কোয়েরিগুলি উত্তোলন করুন যা tsql_stackপদক্ষেপ দেয় les

জিম ব্রাউন এর উত্তর থেকে একটি উদাহরণ, যা আমি বিকাশ করেছি, নীচে দেখানো হয়েছে। একটি ট্রিগার 'আমাকে ধরা' টেক্সট দিয়ে ত্রুটি উত্থাপন করে। XEvent সেশনটি কেবল 'আমাকে ধরা' এর মতো পাঠ্য সহ ত্রুটিগুলি ধরা দেয়।

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

এখন, আপনি যদি এক্সএভেন্ট সেশন (এসএসএমএস, অবজেক্ট এক্সপ্লোরার, ম্যানেজমেন্ট, এক্সটেন্ডেড ইভেন্টস, সেশনস, ক্যাচ_ইনসারেশন_ইনটো_স্টেস্ট) চালু করেন, usp_RootProcIDTest এক্সিকিউট করুন এবং এক্সএভেন্ট সেশনের রিং বাফারটি দেখুন, আপনি এক্সএমএলটি দেখতে পাবেন যাতে নোড রয়েছে <action name="tsql_stack" package="sqlserver">। ফ্রেম নোডের ক্রম রয়েছে। handleসিস্টেমের ফাংশন 'sys.dm_exec_sql_text' এবং 'ভয়েইল'-তে একটি' গুনের বৈশিষ্ট্যের মানগুলি রাখুন :

-- 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);

একটি এক্সিকিউশন কল স্ট্যাক উদাহরণ

এক্সএভেন্ট আপনাকে এর থেকে অনেক বেশি কিছু করতে দেয়! তাদের শেখার সুযোগ মিস করবেন না!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.