কীভাবে একটি টি-এসকিউএল ট্রিগার তৈরি হয় যা কেবলমাত্র সত্যিকারের পরিবর্তনগুলিতে আগুন ধরে?


9

আমার আপডেট এবং INSERT এ একটি টেবিল ট্রিগার রয়েছে যা অন্য টেবিলে একটি সারি যুক্ত করে। এটির জন্য কেবল চারটি কলামের একটির পরিবর্তিত হলে একটি সারি যুক্ত করা দরকার। আমি পরিবর্তনের জন্য পরীক্ষার জন্য আইএফ আপডেট (করল) ব্যবহার করার চেষ্টা করেছি তবে এটির অন্ধ দাগ রয়েছে। এটি কেবলমাত্র পরীক্ষা করে যে কিছু মান এসেছিল I আমাকে আরও গভীরতর হওয়া দরকার, সত্যিকারের পরিবর্তন ঘটেছে তা দেখতে আমার পুরানো এবং নতুন মানগুলির তুলনা করতে হবে। এটি INSERT এবং আপডেট আপডেট উভয়ের সাথে কাজ করতে হবে।

একটি আপডেটের ক্ষেত্রে এটি সহজ কারণ সন্নিবেশ করা এবং মোছা উভয় টেবিলেরই মান রয়েছে যা আমি ট্রিগারটির মধ্যে তুলনা করতে পারি। তবে INSERT- এর জন্য কেবল সন্নিবেশ সারণীর মান রয়েছে। কারণ একই ট্রিগারে আমার এই সমস্ত দরকার, আমি কীভাবে এই INSERT কেস পরিচালনা করব?

ট্রিগারটির স্ক্রিপ্ট এখানে আমি সংশোধন করতে চাই:

ALTER TRIGGER [dbo].[trATPerson_alter] 
   ON  [mydb].[dbo].[AT_Person]
   AFTER INSERT,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    -- Not all updates require a push
    IF (UPDATE([First_Name]) OR UPDATE([Last_Name]) OR UPDATE([JobCode]) OR UPDATE([Inactive]))
    BEGIN
        INSERT INTO [mydb].[dbo].[AT_Person_To_Push] (
                [Facility],
                [VendorID],
                [Person_code],
                [First_Name],
                [Last_Name],
                [JobCode],
                [Alink],
                [Inactive]
            )
        SELECT  [Facility],
                [VendorID],
                [Person_code],
                [First_Name],
                [Last_Name],
                [JobCode],
                [Alink],
                [Inactive]
        FROM inserted 
    END
END

2
"আইএফ আপডেট (<কলাম>)" ব্যবহারের উপর একটি দ্রুত শব্দ। এটি সত্য হয় যদি ডিএমএল কলামের জন্য একটি মান নির্দিষ্ট করে, মানটি আসলে পরিবর্তন হয়েছে কিনা তা নির্বিশেষে returns
জোনাথন ফাইট

উত্তর:


18

আপনি এক্সসেট সেট অপারেটরের সাহায্যে INSERT এবং আপডেট উভয়ই পরিচালনা করতে পারেন। এটি কেবলমাত্র একটি অন্তর্ভুক্ত থাকলে বা এটির কোনও কলামের জন্য আলাদা মান সহ একটি আপডেট DATE

IF EXISTS (
           SELECT First_Name, Last_Name, JobCoe, Inactive FROM inserted
           EXCEPT
           SELECT First_Name, Last_Name, JobCoe, Inactive FROM deleted
          )
BEGIN...

এটি বিভিন্ন কলাম-আপডেট হওয়া ফাংশনগুলি দেখার চেয়ে অনেক বেশি মার্জিত। আমরা কিছু ফ্রন্ট-এন্ড কোডযুক্ত তাদের একত্রিত করেছি কেবলমাত্র পরিবর্তিত মানগুলিতে প্রেরণ করতে (অনেকগুলি ঝাঁকুনির পরে)। একটি এক্সপ্যাক্ট ব্যবহার করা আরও অনেক বেশি অর্থবোধ করে।
পিটার শোট

2
কোনও আপডেটে 2 টি সারি "অদলবদল করা" ক্ষেত্রে এটি কাজ করে না। যদি আমাদের মধ্যে দুটি জন স্মিথ থাকে যাদের জবকোডগুলি আপডেট হওয়া প্রয়োজন (প্রথম জন 1 থেকে 2; দ্বিতীয় জন 2 থেকে 1) - এটি বলবে কোনও আপডেট হয়নি।
স্টিভেন হিবল

2
@ স্টিভেন হিবল - সম্ভব হওয়ার পরে এটি কতটা সম্ভব? উপরের সিলেক্ট স্টেটমেন্টগুলিতে পিকে কলামগুলি অন্তর্ভুক্ত করে সেই ক্ষেত্রে সহজেই প্রতিকার করা যেতে পারে।
চাদ এস্টেস

1
আমি বলব সম্ভাবনাটি ডেটা উত্স এবং খারাপ ডেটা প্রবেশের সম্ভাবনার উপর নির্ভর করে। "উফ, ভুল জন স্মিথ ..." দেখে মনে হয় না যে এটি কখনই ঘটবে না । যাই হোক না কেন, এটি মাল্টি-সারি আপডেটের অন্য অর্ধেকটিকে সম্বোধন করে না: আপনি কীভাবে পরিবর্তনগুলি সারণী সন্নিবেশ করানোর বিষয়টি নিশ্চিত করবেন? এটি EXISTSপরীক্ষা করে যে কোনও সারি পরিবর্তিত হয়েছে। আপনি যদি প্রশ্নটি থেকে সন্নিবেশটি রাখেন, আপনি তখন সমস্ত আপডেট হওয়া সারিগুলিকে লগইন করবেন যখন অর্থবোধক উপায়ে কেবলমাত্র একটি পরিবর্তন হয়।
স্টিভেন হিবল

2

কোনও আপডেট একাধিক সারিগুলিকে প্রভাবিত করতে পারে, আপনাকে দুটি জিনিস থেকে রক্ষা করতে হবে:

  1. আমরা আপডেটগুলি বিবেচনা করতে চাই যা একই সারিগুলির মধ্যে মান অদলবদল করে। যদি দু'জন জন স্মিথের তাদের জবকোডগুলি আপডেট হওয়ার প্রয়োজন হয় (প্রথম জন 1 থেকে 2; দ্বিতীয় জন 2 থেকে 1 পর্যন্ত), আমাদের উভয়কেই আপডেট করা হয়েছে বলে আমাদের সাবধানতা অবলম্বন করা উচিত।
  2. আমরা কেবল পরিবর্তিত সারিগুলিতে লগ ইন করতে চাই AT_Person_To_Push। যদি 5 টি সারি আপডেট হয় তবে কেবল আমাদের 2 যত্নশীল এমনভাবে আপডেট করা হয়, তবে আমাদের কেবল দুটি প্রাসঙ্গিক সারিগুলি প্রক্রিয়া করতে হবে।

আমি কীভাবে এটি পরিচালনা করব তা এখানে:

  1. বামে যোগ insertedদিন deleted, কারণ insertedসন্নিবেশ এবং আপডেটের deletedজন্য সারি থাকবে যখন কেবল আপডেটের জন্য সারি থাকবে।
  2. ব্যবহার করুন EXISTSসঙ্গে EXCEPTসারি যেখানে এটি insertedমান থেকে পৃথক deletedমান। আপনি ব্যবহার করতে পারবেন না i.First_Name != d.First_Name OR i.Last_Name != d.Last_Name...কারণ মুছে ফেলা টেবিলটি খালি হবে (এবং বাম জোয়ান শূন্যগুলি ফিরে আসবে) যখন ট্রিগার একটি INSERT পরিচালনা করছে।
  3. এর মধ্যে কেবল প্রভাবিত সারিগুলি sertোকান AT_Person_To_Push
ALTER TRIGGER [dbo].[trATPerson_alter] 
   ON  [mydb].[dbo].[AT_Person]
   AFTER INSERT,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    INSERT INTO [mydb].[dbo].[AT_Person_To_Push] (
            [Facility],
            [VendorID],
            [Person_code],
            [First_Name],
            [Last_Name],
            [JobCode],
            [Alink],
            [Inactive]
        )
    SELECT  i.[Facility],
            i.[VendorID],
            i.[Person_code],
            i.[First_Name],
            i.[Last_Name],
            i.[JobCode],
            i.[Alink],
            i.[Inactive]
    FROM inserted i
         LEFT JOIN deleted d
           ON i.Person_code = d.Person_code
    -- Check for changes that require a push
    WHERE EXISTS (SELECT i.[First_Name], i.[Last_Name], i.[JobCode], i.[Inactive]
                  EXCEPT
                  SELECT d.[First_Name], d.[Last_Name], d.[JobCode], d.[Inactive]);
END

1

এটা চেষ্টা কর,

Declare @Acton int=0

If exists (Select 1 from inserted)
set @Acton=1

If exists (Select 1 from deleted)
set @Acton=@Acton+2

if(@Action=1) -- Only insert

if(@Action=3) -- Only Update
begin
IF (UPDATE([First_Name]) OR UPDATE([Last_Name]) OR UPDATE([JobCode]) OR UPDATE([Inactive]))
Begin

End
end

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