সমস্ত রেফারেন্সিং বিদেশী কীতে প্রাথমিক কী আপডেট ক্যাসকেড করুন


11

বিদেশী কীগুলি উল্লেখ করার সাথে সাথে আপডেটটিকে ক্যাসকেড করে কোনও প্রাথমিক কী কলাম মানটি আপডেট করা সম্ভব?

# সম্পাদনা 1: যখন আমি ফলোইনকি কোয়েরি চালাই

select * from sys.foreign_keys where referenced_object_id=OBJECT_ID('myTable') 

, আমি দেখতে পাচ্ছি আপডেট_ রেফারেন্সিয়াল_অ্যাকশন 0 তে সেট করা আছে। সুতরাং আমার প্রাথমিক কীগুলির কলামগুলি আপডেট করার পরে কোনও পদক্ষেপ নেওয়া হয়নি। বিদেশী কীগুলিকে ক্যাসকেড আপডেটের জন্য কীভাবে আপডেট করতে পারি ?

# সম্পাদনা 2:
আপনার স্কিমায় সমস্ত বিদেশী কী তৈরি বা বাদ দেওয়ার জন্য স্ক্রিপ্ট আউট করার জন্য নিম্নলিখিত স্ক্রিপ্টটি চালান ( এখান থেকে নেওয়া )

DECLARE @schema_name sysname;

DECLARE @table_name sysname;

DECLARE @constraint_name sysname;

DECLARE @constraint_object_id int;

DECLARE @referenced_object_name sysname;

DECLARE @is_disabled bit;

DECLARE @is_not_for_replication bit;

DECLARE @is_not_trusted bit;

DECLARE @delete_referential_action tinyint;

DECLARE @update_referential_action tinyint;

DECLARE @tsql nvarchar(4000);

DECLARE @tsql2 nvarchar(4000);

DECLARE @fkCol sysname;

DECLARE @pkCol sysname;

DECLARE @col1 bit;

DECLARE @action char(6);  

DECLARE @referenced_schema_name sysname;



DECLARE FKcursor CURSOR FOR

     select OBJECT_SCHEMA_NAME(parent_object_id)

         , OBJECT_NAME(parent_object_id), name, OBJECT_NAME(referenced_object_id)

         , object_id

         , is_disabled, is_not_for_replication, is_not_trusted

         , delete_referential_action, update_referential_action, OBJECT_SCHEMA_NAME(referenced_object_id)

    from sys.foreign_keys

    order by 1,2;

OPEN FKcursor;

FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name

    , @referenced_object_name, @constraint_object_id

    , @is_disabled, @is_not_for_replication, @is_not_trusted

    , @delete_referential_action, @update_referential_action, @referenced_schema_name;

WHILE @@FETCH_STATUS = 0

BEGIN



      IF @action <> 'CREATE'

        SET @tsql = 'ALTER TABLE '

                  + QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)

                  + ' DROP CONSTRAINT ' + QUOTENAME(@constraint_name) + ';';

    ELSE

        BEGIN

        SET @tsql = 'ALTER TABLE '

                  + QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)

                  + CASE @is_not_trusted

                        WHEN 0 THEN ' WITH CHECK '

                        ELSE ' WITH NOCHECK '

                    END

                  + ' ADD CONSTRAINT ' + QUOTENAME(@constraint_name)

                  + ' FOREIGN KEY (';

        SET @tsql2 = '';

        DECLARE ColumnCursor CURSOR FOR

            select COL_NAME(fk.parent_object_id, fkc.parent_column_id)

                 , COL_NAME(fk.referenced_object_id, fkc.referenced_column_id)

            from sys.foreign_keys fk

            inner join sys.foreign_key_columns fkc

            on fk.object_id = fkc.constraint_object_id

            where fkc.constraint_object_id = @constraint_object_id

            order by fkc.constraint_column_id;

        OPEN ColumnCursor;

        SET @col1 = 1;

        FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;

        WHILE @@FETCH_STATUS = 0

        BEGIN

            IF (@col1 = 1)

                SET @col1 = 0;

            ELSE

            BEGIN

                SET @tsql = @tsql + ',';

                SET @tsql2 = @tsql2 + ',';

            END;

            SET @tsql = @tsql + QUOTENAME(@fkCol);

            SET @tsql2 = @tsql2 + QUOTENAME(@pkCol);

            FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;

        END;

        CLOSE ColumnCursor;

        DEALLOCATE ColumnCursor;

       SET @tsql = @tsql + ' ) REFERENCES ' + QUOTENAME(@referenced_schema_name) + '.' + QUOTENAME(@referenced_object_name)

                  + ' (' + @tsql2 + ')';

        SET @tsql = @tsql

                  + ' ON UPDATE ' + CASE @update_referential_action

                                        WHEN 0 THEN 'NO ACTION '

                                        WHEN 1 THEN 'CASCADE '

                                        WHEN 2 THEN 'SET NULL '

                                        ELSE 'SET DEFAULT '

                                    END

                  + ' ON DELETE ' + CASE @delete_referential_action

                                        WHEN 0 THEN 'NO ACTION '

                                        WHEN 1 THEN 'CASCADE '

                                        WHEN 2 THEN 'SET NULL '

                                        ELSE 'SET DEFAULT '

                                    END

                  + CASE @is_not_for_replication

                        WHEN 1 THEN ' NOT FOR REPLICATION '

                        ELSE ''

                    END

                  + ';';

        END;

    PRINT @tsql;

    IF @action = 'CREATE'

        BEGIN

        SET @tsql = 'ALTER TABLE '

                  + QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)

                  + CASE @is_disabled

                        WHEN 0 THEN ' CHECK '

                        ELSE ' NOCHECK '

                    END

                  + 'CONSTRAINT ' + QUOTENAME(@constraint_name)

                  + ';';

        PRINT @tsql;

        END;

    FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name

        , @referenced_object_name, @constraint_object_id

        , @is_disabled, @is_not_for_replication, @is_not_trusted

        , @delete_referential_action, @update_referential_action, @referenced_schema_name;

END;

CLOSE FKcursor;

DEALLOCATE FKcursor;  

DROP বিদেশী কী স্ক্রিপ্ট উত্পন্ন করতে, ঘোষণার ধারাটিতে 'DROP' এর সমান হতে @ অ্যাকশন মানটি সংশোধন করুন:

DECLARE @action char(6) = 'DROP';

উত্তর:


9

আপনি যদি বৈদেশিক কী সীমাবদ্ধতাগুলি হিসাবে সংজ্ঞায়িত করে থাকেন ON UPDATE CASCADEতবে প্রাথমিক কী মানটি যা পরিবর্তিত হয়েছিল তা সেই সীমাবদ্ধতার সাথে সমস্ত বিদেশী কীতে ক্যাসকেড করা উচিত।

আপনার যদি ON UPDATE CASCADEসীমাবদ্ধতা না থাকে তবে আপডেটটি সম্পূর্ণ করতে আপনার স্ক্রিপ্ট তৈরি করতে হবে।

সম্পাদনা: যেহেতু আপনার ON UPDATE CASCADEপ্রতিবন্ধকতা নেই তবে আপনি সেটি সেট আপ করতে চান তাই এটি কিছুটা কাজ। এসকিউএল সার্ভার একটি নতুন সেটিংয়ের সীমাবদ্ধতাগুলি পরিবর্তন করতে সমর্থন করে না।

প্রতিটি টেবিলের মাধ্যমে পুনরাবৃত্তি করা দরকার যা পিকে টেবিলের সাথে এফকে বাধা দেয়। এফকে সহ প্রতিটি টেবিলের জন্য:

  1. বিদ্যমান এফকে সীমাবদ্ধতা ফেলে দেওয়ার জন্য টেবিলটি পরিবর্তন করুন।
  2. প্রশ্নে থাকা এফকে-র জন্য পুনরায় আপডেট ক্যাসকেড সীমাবদ্ধতা তৈরি করতে আবার টেবিলটি পরিবর্তন করুন।

এটি কিছুটা প্রচেষ্টা নেয়, তবে আপনার ক্ষেত্রে আপনার প্রতিবন্ধকতা যথাযথভাবে সেট করা যায়।

সম্পাদনা 2: আপনার যে তথ্য প্রয়োজন তা সিস.ফরাইন_কিজে পাওয়া যায়। আপনার প্রয়োজনীয় সমস্ত তথ্য পেতে আপনি এই টেবিলটি থেকে নির্বাচন করতে পারেন।

জন পল কুকের একটি পোস্ট এখানে পাওয়া যাবে:

( http://social.technet.microsoft.com/wiki/contents/articles/2958.script-to-create-all-foreign-keys.aspx )

এই কোডটি একটি ডাটাবেসে সমস্ত এফকে সীমাবদ্ধতা ফেলে দেবে। আপনার ডাটাবেসে যে পরিবর্তনগুলি চান তা করতে আপনি সেখান থেকে কাজ করতে সক্ষম হবেন।


আরও তথ্যের জন্য আমার সম্পাদনা দেখুন
mounaim

আপনি কীভাবে সমস্ত বিদেশী কীগুলি @RLF স্ক্রিপ্ট করবেন তা জানেন?
mounaim

@ মৌনাইম - স্ক্রিপ্ট তৈরির বিষয়ে একটি নোট সহ আপডেট হয়েছে।
আরএলএফ

আমি একই জিনিস এবং একই লিঙ্কে কাজ করছিলাম আমার সম্পাদনা দেখুন @ আরএলএফ
মওনাইম

1
এখানে ডিবিএ এসই-তে কোড ব্লক অন্তর্ভুক্ত করা ভাল কারণ অন্য ওয়েবসাইটগুলির লিঙ্কগুলি পরে ভাঙতে পারে :)
মওনাইম

4

আপনি অবশ্যই পারবেন। ON UPDATE CASCADEআপনি যা খুঁজছেন তা

এখানে কীভাবে করা যায় তা এখানে একটি ছোট: http://sqlandme.com/2011/08/08/sql-server-how-to-cassade-updates-and-deletes-to-related-tables/

মূলত, আপনি যখন পিকে সংশোধন করবেন, ক্যাসকেডটি বাইরে চলে যাবে এবং সমস্ত এফকে আপডেট করবে যা এটি উল্লেখ করে। এটি আপনার CREATEবিবৃতিতে করা যেতে পারে , ঠিক যেমন আপনি একটি করছেনCASCADE DELETE

আপনি যখন এটি করেন তখন জিনিসগুলিতে নজর রাখুন কারণ আমি এটি বুঝতে পেরেছি, ক্যাসকেড আসলে বিচ্ছিন্নতার পর্যায়ে চলে SERIALIZABLE(সাধারণত, এসকিউএল READ COMMITTEDডিফল্টরূপে চালিত হয় ) তাই কোনও ব্লকিং সমস্যা দেখার জন্য লক্ষ্য রাখুন।

বিচ্ছিন্নতা মাত্রা উপর অতিরিক্ত তথ্য এই প্রবন্ধে পাওয়া যাবে: http://msdn.microsoft.com/en-us/library/ms173763.aspx


3

সমস্ত বিদেশী কীগুলি ক্যাসকেড আপডেট হিসাবে সংজ্ঞায়িত করুন

আপনি যদি এটি না করে থাকেন তবে আপনাকে তা করতে হবে

  1. নতুন প্রাথমিক কী সহ একটি নতুন সারি তৈরি করুন
  2. সমস্ত শিশু টেবিল আপডেট করুন
  3. পুরানো সারি সরান

.. অবশ্যই একটি লেনদেন এবং ব্যর্থ হতে পারে যে অন্যান্য প্রতিবন্ধকতা জন্য সন্ধান


ধন্যবাদ @ জিবিএন আমার বিদেশী কীগুলি আপডেট করা কি সম্ভব বা আমি কেবল এগুলি ফেলে দিতে এবং অন ক্যাসকেড আপডেট আপডেটের সাথে তাদের পুনরায় তৈরি করতে পারি?
mounaim

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