সারিগুলি এক টেবিল থেকে অন্য টেবিলে সরিয়ে নেওয়া হচ্ছে


9

সংরক্ষণাগার প্রক্রিয়ার অংশ হিসাবে আমি একটি ডাটাবেস থেকে অন্য ডাটাবেসে রেকর্ডগুলি সরিয়ে নিচ্ছি। আমি গন্তব্য সারণিতে সারিগুলি অনুলিপি করতে এবং তারপরে উত্স টেবিল থেকে একই সারিগুলি মুছতে চাই।

আমার প্রশ্ন হ'ল সারিগুলি মোছার আগে প্রথম সন্নিবেশ সফল হয়েছিল কিনা তা পরীক্ষা করার সবচেয়ে কার্যকর উপায় কী।

আমার ধারণাটি এটি, তবে আমি মনে করি এর থেকে আরও ভাল উপায় আছে:

@num_records=select count(ID) from Source_Table where (criteria for eligible rows)

insert * into Destination_Table where (criteria for eligible rows)

if ((select count(ID) from Destination_Table where (criteria) )=@numrecords)

delete * from Source_Table where (criteria)

এটি কি RAISERROR ফাংশনের সাথে একত্রিত করা আরও ভাল / সম্ভব? ধন্যবাদ!

উত্তর:


13

আমি স্পষ্ট লেনদেনের পাশাপাশি ট্রাই / ক্যাচ সিনট্যাক্সের পরামর্শ দেব । এই সমাধানটির জন্য আমার ধারণাটি হ'ল sertোকানো ব্যর্থতার কারণটি হ'ল ট্র্যাফেবল এসকিউএল ত্রুটি (যেমন কী লঙ্ঘন, ডেটাটাইপ মেলামেশা / রূপান্তর ত্রুটি ইত্যাদি)। কাঠামোটি দেখতে এরকম হবে:

BEGIN TRAN

BEGIN TRY
  INSERT INTO foo(col_a,col_b,col_c,recdate)
  SELECT col_a,col_b,col_c,recdate
  FROM bar
  WHERE recdate BETWEEN @startdate AND @enddate

  DELETE FROM bar
  WHERE recdate BETWEEN @startdate AND @enddate

  COMMIT TRAN
END TRY
BEGIN CATCH
  ROLLBACK TRAN
END CATCH

এই কাঠামোটি যেভাবে কাজ করে, INSERT বা মুছে ফেলার ক্ষেত্রে যদি কোনও ত্রুটি দেখা দেয় তবে পুরো ক্রিয়াটি আবার ঘুরিয়ে ফেলা হয়। এটি গ্যারান্টি দেয় যে সম্পূর্ণ ক্রিয়াটি সম্পন্ন করতে অবশ্যই সফল হতে হবে। আপনি মনে হয়েছে যে, এটা প্রয়োজনীয় ছিল, তাহলে আপনি এটি সঙ্গে মেশা পারে নিক্ষেপ 2012 বা RAISERROR 2008 সালে এবং অতিরিক্ত যুক্তিবিজ্ঞান যোগ করতে পারেন এবং যদি সেই লজিক দেখা হয়নি করেন রোলব্যাক বলপূর্বক পূর্ববর্তী।

আরেকটি বিকল্প হ'ল SET XACT_ABORT চালু করা , যদিও আমি অনুভব করি যে TRY / CATCH সিনট্যাক্স আপনাকে আরও গ্রানুলারিটি দেয়।


19

যদি আপনার সংরক্ষণাগার টেবিলটি না করে

  • এটিতে সংজ্ঞায়িত ট্রিগার সক্ষম করেছে।
  • একটি বিদেশী মূল সীমাবদ্ধতার উভয় পক্ষে অংশ নিন।
  • চেক সীমাবদ্ধতা বা সক্ষম সক্ষম নিয়ম রয়েছে।

আপনি এটি এক রাজ্যেও করতে পারেন।

DELETE FROM source_table
OUTPUT deleted.Foo,
       deleted.Bar,
       SYSUTCDATETIME()
INTO archive_table(Foo, Bar, archived)
WHERE  Foo = 1; 

এটি হয় ইউনিট হিসাবে সফল বা ব্যর্থ হবে INSERTএবং আর্কাইভের মধ্যে সারিগুলির সাথে সারি যুক্ত হওয়ার সাথে সাথে সম্ভাব্য রেস শর্তগুলি এড়িয়ে যাবে এবং DELETE(যদিও আপনার WHEREধারাটি যাইহোক এটি সম্ভবত অত্যন্ত সম্ভাবনাময় হতে পারে)।


উপরের কেউই না. আমি মনে করি আমি সেই পথে যেতে পারব, আমি কোড মিনিমালিজম পছন্দ করি। যদি সন্নিবেশ কোনও কারণে ব্যর্থ হয় তবে আমি রেকর্ডগুলি হারাতে চাই না। (যেমন: টেবিল লকিং, সময়সীমা ইত্যাদি) আপনাকে ধন্যবাদ!
দিনা

@ ডিনা - আপনি কি এই নির্দেশ দিয়েছিলেন যে এই OUTPUTধারাটির মাধ্যমে সম্ভব ? এটি সমস্ত এক বিবৃতি কারণ এটি নয়। এছাড়াও দু'বার সারিগুলি পড়ার বিষয়টি এড়িয়ে যায় (এবং সম্ভবত সন্নিবেশের জন্য পড়ার জন্য এবং মোছার জন্য পড়ার মধ্যে যে সারিগুলি যুক্ত করা হয়েছিল তা হারিয়ে
মার্টিন স্মিথ

হ্যাঁ, এটাই আমি বোঝাতে চাইছিলাম ধন্যবাদ, আমি আপনার বক্তব্য দেখতে।
দিনা

এফডাব্লুআইডাব্লু - এই পদ্ধতিটি মূল টেবিলের আকারের তুলনায় লগফাইলে বৃদ্ধি ঘটবে। আপনি এটির সাথে বেঁচে থাকতে পারবেন তা নিশ্চিত করুন। যদি আপনি না করতে পারেন তবে এটি ডিলিট টপ (এন) এবং অ্যাড লুপের সাহায্যে ব্যাচগুলিতে বিভক্ত করুন যা @@ সার্কাউন্টের ভেরিয়েবল পরীক্ষা করে।
Wjdavis5

1

সংরক্ষণাগারটি করার বিষয়ে আমি যেভাবে ভেবেছি (যা আমি নিশ্চিত নিখুঁত নয়) তা হ'ল 'আর্কাইভ' এর মতো নতুন সংরক্ষণাগার টেবিলটিতে কিছুটা কলাম যুক্ত করা যা রেকর্ডটির সফল স্থানান্তরের পরে 1 এর মান হবে। এবং একবার আপনি সমস্ত রেকর্ড স্থানান্তর করলে, আপনি সংরক্ষণাগার টেবিল থেকে '1' অর্থাত্ এই 'আর্কাইভ' ক্ষেত্রের মানটি অনুসন্ধান করার সময় একটি মুছুন অপারেশন করতে পারেন।

এবং আমি মাইকের সাথে ট্রাই / ক্যাচ ব্যবহারের সাথে একমত হই।


1

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

INSERT dbo.newtable(
      name,
      department,
      Salary
) SELECT 
            name,
            FirstName,
            Lastname
      FROM    (
           DELETE dbo.oldtable
           OUTPUT
                   DELETED.name,
                   DELETED.department,
                   DELETED.Salary
           WHERE ID  IN ( 1001, 1003, 1005 )
      ) AS RowsToMove;

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