এসকিউএল সার্ভার: কেবলমাত্র আপনার বর্তমান সেশনের জন্য কোনও আপডেটের জন্য ট্রিগার অক্ষম করবেন কীভাবে?


15

আমি এসকিউএল সার্ভার ২০০৮ আর 2 এ কাজ করছি।

আমার একটি টেবিল সুবিধা রয়েছে যা টাইউ_বেনিফিট নামে একটি সংক্ষেপণ , আপডেট আপডেটের পরে রয়েছে

1 সারি আপডেট করার জন্য আমি এই টেবিলটির জন্য একটি আপডেট আপডেট লিখতে চাই তবে আমি এটির ট্রিগারটি চালিত করতে চাই না। আমি জানি আমি আপডেটের আগে ট্রিগারটি অক্ষম করতে পারি এবং তারপরে আপডেটের পরে ট্রিগার সক্ষম করতে পারি:

DISABLE TRIGGER tiu_benefit ON benefit;  
GO  
UPDATE benefit SET editor = 'srh' where benefit_id = 9876
GO
ENABLE TRIGGER tiu_benefit ON benefit;  
GO  

তবে এই অক্ষম এবং সক্ষম ট্রিগারটি বর্তমানে লগ ইন করা সমস্ত ব্যবহারকারীকে প্রভাবিত করবে। সুতরাং আপনার স্ক্রিপ্ট দ্বারা ট্রিগারটি অক্ষম থাকা অবস্থায় অন্য ব্যবহারকারী একটি আপডেট / ইনসার্ট চালানোর সম্ভাবনা রয়েছে যা ভাল নয়। আমি কেন কেবলমাত্র আমার বর্তমান সেশনের জন্য ট্রিগার অক্ষম করতে এবং সক্ষম করতে চাই ts এটা কি সম্ভব? যদি হ্যাঁ দয়া করে কিভাবে বলুন।

ধন্যবাদ


1
আপনি যদি নিজের ট্রিগারটি সংশোধন করতে না পারেন তবে উত্তরটি হ'ল না।
jyao

উত্তর:


6

আমি এটি সম্পর্কে কিছু পরীক্ষা করেছি এবং আমি মনে করি আপনি যদি একক লেনদেনে আপনার প্রক্রিয়াটি চালান তবে আপনি ভাল হয়ে যাবেন।

BEGIN TRANSACTION
GO

DISABLE TRIGGER tiu_benefit ON benefit;
GO

UPDATE benefit
SET editor = 'srh'
WHERE benefit_id = 9876
GO

ENABLE TRIGGER tiu_benefit ON benefit;
GO

--Decide to commit or rollback

--commit
--rollback 

আমার পরীক্ষায় আমি কেবল প্রথম BEGIN TRANSACTIONএবং DISABLE TRIGGERপ্রথমটিকে হাইলাইট করেছি এবং কার্যকর করেছি । আমি তখন একটি নতুন (দ্বিতীয়) ক্যোয়ারী জানালা খোলা এবং বিভিন্ন DML বিবৃতি (রান করার চেষ্টা SELECT, INSERT, UPDATE DELETE) বেস টেবিল বিরুদ্ধে। দ্বিতীয় ক্যোয়ারী উইন্ডোতে বেস টেবিলটি অ্যাক্সেসের সমস্ত প্রয়াস স্পষ্ট লেনদেনের সাথে উইন্ডোতে রাখা লকগুলিতে অপেক্ষা করেছিল। একবার আমি আমার স্পষ্ট লেনদেনের প্রতিশ্রুতিবদ্ধ (বা ঘূর্ণায়মান) হয়ে গেলে দ্বিতীয় উইন্ডোটি টেবিলটি অ্যাক্সেস করতে সক্ষম হয়েছিল।


এটি কাজ করবে, তবে লকগুলি আপনাকে লেনদেনটি কতক্ষণ উন্মুক্ত রাখবে তার উপর নির্ভর করে প্রবাহিত অজানা সমস্যার সৃষ্টি করতে পারে।
CaM

@ ক্যাম - আমি ধরে নেব যে একটি সারির আপডেটে ওপি কমিট করে বা লেনদেনটি দ্রুত ফিরিয়ে আনবে বলে ধরে নিলে খুব বেশি সময় লাগবে না। আশা করি, এখানে একটি সূচক আছে benefit_id:)
স্কট হডগিন


18

আপনার সমস্যা সমাধানের জন্য, আমাদের সমস্যার জন্য একটি প্রোগ্রামিক পদ্ধতি গ্রহণ করতে হবে। আপনি এখানে যেতে পারেন দুটি রুট আছে। এই পদ্ধতির প্রয়োজন হওয়ার কারণ হ'ল কারণ আপনি কোনও নির্দিষ্ট বিবৃতিটির জন্য ট্রিগার অক্ষম করতে পারবেন না, এটি কেবলমাত্র টেবিলের সম্পূর্ণতার জন্য অক্ষম করা যেতে পারে।

বিকল্প 1: প্রসঙ্গ_Info ()

এমএস এসকিউএল টিপসে স্যামুয়েল ভঙ্গার দুর্দান্ত উদাহরণ ছিল:

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

এখন যখন স্যামুয়েল ট্রিগারটি কার্যকর করতে চায় না, তারা এটি ব্যবহার করে:

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

Context_Info বর্তমান অধিবেশন সম্পর্কিত তথ্য দখল করতে নিম্নলিখিত সিস্টেমের দর্শনগুলি ব্যবহার করে:

  • sys.dm_exec_requests

  • sys.dm_exec_sessions

  • sys.sysprocesses

এখানে মতাদর্শটি হ'ল আপনি যে বাইনারি স্ট্রিংটি স্থাপন করছেন তা কেবল বর্তমান সেশনেই উন্মুক্ত, সুতরাং যখন ট্রিগারটি আপনার অধিবেশন চলাকালীন কার্যকর হবে তখন এটি Context_infoফাংশনের সুযোগ এবং পরিবর্তনশীল সেটিংটি দেখতে পাবে এবং এটি ট্রিগারটির পালানোর অংশে চলে যাবে jump পরিবর্তে.

বিকল্প 2: টেম্প টেবিল

Itzik বিন্-Gan থেকে একটি আছে দুর্দান্ত সমাধান তার পরে বইয়ে হয়: তার বই "টি-SQL প্রোগ্রামিং ইনসাইড মাইক্রোসফট SQL সার্ভার 2008 টি-SQL প্রোগ্রামিং" এ টি-এসকিউএল অনুসন্ধানcontext_infoফাংশনটি দিয়ে এটির প্রাথমিক সমস্যাটি হ'ল গৌণ টেম্পডিবি ওভারহেড।

অবাক করে দেওয়ার জন্য কিন্তু বইগুলির প্লটটি নষ্ট না করার জন্য (আমি মনে করেছি সেগুলি কেনা এবং পড়ার পক্ষে মূল্যবান), আপনি আপনার ট্রিগারটি পরিবর্তন করতে পারবেন।

আপনার ট্রিগারটিতে অস্থায়ী টেবিলের জন্য একটি পরীক্ষা করা উচিত। যদি অস্থায়ী টেবিলটি বিদ্যমান থাকে তবে ট্রিগারটির শেষ হওয়া উচিত এবং ক্রিয়াগুলি সম্পাদন করা উচিত নয়।

আপডেট বিবৃতিতে আপনি সম্পাদন করতে চান, অস্থায়ী টেবিলটি প্রথমে তৈরি করুন। এটি ট্রিগার হিসাবে একই লেনদেনে দেখা যাবে এবং এটি ট্রিগারটি আপনার বক্তব্যকে উপেক্ষা করবে।

ট্রিগার উদাহরণ:

CREATE TRIGGER TRIGGERNAME ON TABLENAME for INSERT AS

IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
GO

আপনি যখন ট্রিগারটি চালাতে চান না তখন সূচনা বিবরণের উদাহরণ:

CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);

আপনার উদাহরণের জন্য এটি পুরোপুরি রেখে দেওয়া:

ALTER TRIGGER tiu_benefit ON benefit FOR 
... 
AS
...
IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
--... rest of code here
GO

CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);
UPDATE benefit SET editor = 'srh' where benefit_id = 9876;
GO

2
আমি ট্রিগারটিতে টেম্প টেবিলের পরিবর্তে প্রসঙ্গ_ইনফো () ব্যবহার করব। অন্য কথায়, যদি কোনও ট্রিগার প্রসঙ্গ_আইনফো একটি নির্দিষ্ট মান প্রদান করে তা সনাক্ত করে, ট্রিগার সেই অনুযায়ী কাজ করবে। : আপনি এখানে প্রাসঙ্গিক তাই প্রশ্ন উল্লেখ করতে পারে stackoverflow.com/questions/3025662/...
jyao

1
এছাড়াও আপনি একটি চেক অনুরূপ করা হতে পারে context_infoব্যবহার original_login()করে একটি নির্দিষ্ট ব্যক্তির ট্রিগার আঘাত করা হয় না চালানোর ট্রিগার বলতে।
কেনেথ ফিশার

2

আমি হয় CONTEXT_INFOবা নতুন ব্যবহার করতে হবে SESSION_CONTEXT। উভয়ই সেশন ভিত্তিক মান।

  • CONTEXT_INFOএকক VARBINARY(128)মান। এটি কমপক্ষে এসকিউএল সার্ভার 2000 সাল থেকে উপলব্ধ । এটি ডিএমভি দ্বারা ফিরিয়ে নেওয়া ক্ষেত্র হিসাবে CONTEXT_INFOযে কারও সাথেই দেখা যায় । আমি এটি আগে ব্যবহার করেছি এবং এটি বেশ ভালভাবে কাজ করে।VIEW SERVER STATEsys.dm_exec_sessions

    SET- এর মাধ্যমে সেট করুন CONTEXT_INFO CONTEXT_INFO () অথবা sys.dm_exec_sessions এর
    মাধ্যমে যান

    আপনি যে ধরণের মান সংরক্ষণ করছেন তার উপর নির্ভর করে CONTEXT_INFO, কিছু সচেতন হতে হবে। আমি নিম্নলিখিত ব্লগ পোস্টে এটি আবরণ:

    কেন CONTEXT_INFO () SET CONTEXT_INFO দ্বারা নির্ধারিত সঠিক মানটি ফেরত দেয় না?

  • সেশন_কন্টেক্সট হ'ল একটি মান / মান জোড় SQL_VARIANT। এটি এসকিউএল সার্ভার ২০১ 2016 সালে প্রবর্তিত হয়েছিল different বিভিন্ন উদ্দেশ্যে মানগুলির পৃথকীকরণটি বেশ দুর্দান্ত। সেশন_কন্টেক্সট কেবলমাত্র বর্তমান অধিবেশন দ্বারা দৃশ্যমান।

    Sp_set_session_context এর মাধ্যমে এই মানটি সেট
    করুন SESSION_CONTEXT এর মাধ্যমে এই মানটি পান

স্থানীয় অস্থায়ী টেবিল বিকল্প এবং এমনকী অক্ষম / সক্ষম ট্রিগার বিকল্পটি সম্পর্কে বিবেচনা করার একটি বিষয়: এগুলির উভয়ের জন্য কিছু পরিমাণ লকিং এবং ট্রান লগ ক্রিয়াকলাপ প্রয়োজন। এই দুটি অপশনই ন্যূনতম হলেও বিতর্ক করার সম্ভাবনা বাড়িয়ে তোলে। দুটি "প্রসঙ্গ" বিকল্পগুলি কেবল হালকা ওজন / মেমরির হওয়া উচিত।


প্রসঙ্গ_আইনফো একটি ব্যথা উপশমকারী, আপনি যখনই কোনও প্রোডাক্ট ডেটা পরিবর্তন চালাতে চান এটি কার্যকর হয়, বিশেষত ট্রিগার অক্ষম করা অন্য ক্রিয়াকলাপকে ট্রিগারটিকে আগুনে না ডেকে আনতে পারে।
বিজু জোস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.