একটি INSERT বিবৃতি (এসকিউএল সার্ভার) এর আউটপুট মধ্যে উত্স কলামগুলি ব্যবহার করে


16

আমি একটি ব্যাচ প্রসেসিং সন্নিবেশ বিবৃতি লিখছি এবং প্রতিটি আইটেমটি নিজে থেকে লুপিংয়ের পরিবর্তে এবং inোকানো প্রতিটি সারির জন্য SCOPE_IDENTITY () কল করার পরিবর্তে sertedোকানো আইডির ট্র্যাক রাখতে একটি টেম্প টেবিল ব্যবহার করতে চাই।

যে তথ্যটি সন্নিবেশ করা দরকার সেগুলির মধ্যে (অস্থায়ী) আইডি এটির অন্য ডেটার সাথে সংযোগ স্থাপন করে যা অন্য টেবিলে beোকানো উচিত, সুতরাং আমার আসল আইডি এবং অস্থায়ী আইডির ক্রস রেফারেন্স প্রয়োজন।

আমার এতদূর যা আছে তার এটি একটি উদাহরণ:

-- The existing table 
DECLARE @MyTable TABLE (ID INT IDENTITY(1,1), [Name] NVARCHAR(MAX));

-- My data I want to insert
DECLARE @MyInsertData TABLE (ID INT, [Name] NVARCHAR(MAX));
INSERT INTO @MyInsertData ( ID,Name)
VALUES ( -1 , 'bla'),(-2,'test'),(-3,'last');

DECLARE @MyCrossRef TABLE ([NewId] INT, OldId INT);

INSERT INTO @MyTable ( [Name] )
   OUTPUT Inserted.ID, INS.ID INTO @MyCrossRef
   SELECT [NAME] FROM @MyInsertData INS

-- Check the result
SELECT * FROM @MyCrossRef

সমস্যাটি হ'ল আমি আইডিটি গ্রহণ করার জন্য আউটপুট INTO ধারাটি পেতে পারি না, আমি চেষ্টা করেছি @MyInsertData.IDএবং অন্য কৌশলগুলি নিজেরাই টেবিলটিতে যোগদান করার চেষ্টা করেছি , তবে কিছুই কাজ করছে বলে মনে হচ্ছে না।

উত্তর:


28

আসলে, আপনি আপনার পরিবর্তন করে একই জিনিস অর্জন করতে পারেন INSERTএকটি থেকে MERGE। যদিও MERGEবিবৃতিটি এসকিউএল সার্ভারে "উপস্থাপক" করার জন্য একটি সুন্দর ঝরঝরে উপায়, কেবল সন্নিবেশ করার উদ্দেশ্যে আপনাকে এটি ব্যবহার করা থেকে বিরত করার মতো কিছুই নেই:

-- The existing table 
DECLARE @MyTable TABLE (ID INT IDENTITY(1,1), [Name] NVARCHAR(MAX));

-- My data I want to insert
DECLARE @MyInsertData TABLE (ID INT, [Name] NVARCHAR(MAX));
INSERT INTO @MyInsertData ( ID,Name)
VALUES ( -1 , 'bla'),(-2,'test'),(-3,'last');

DECLARE @MyCrossRef TABLE ([NewId] INT, OldId INT);

MERGE INTO @MyTable AS dest
USING @MyInsertData AS ins ON 1=0   -- always false

WHEN NOT MATCHED BY TARGET          -- happens for every row, because 1 is never 0
    THEN INSERT ([Name])
         VALUES (ins.[NAME])

OUTPUT inserted.ID, ins.ID
INTO @MyCrossRef (NewId, OldId);

-- Check the result
SELECT * FROM @MyCrossRef

সুন্দর জিনিসগুলির মধ্যে একটি MERGEহ'ল এটি আপনাকে সোর্স কলামগুলির পাশাপাশি দলে অন্তর্নির্মিত insertedএবং deletedটেবিলগুলিতে অ্যাক্সেস করতে দেয় OUTPUT

আমার কোডটিতে ত্রুটি থাকতে পারে, কারণ আমি আসলে এটি পরীক্ষা করে দেখিনি। কয়েক বছর আগে থেকে আমার ব্লগ পোস্টটি ক্যোয়ারী পারফরম্যান্স সহ আরও কিছুটা বিশদে যায়।


দারুণ! এই সময়টি আমাকে একটি লুপে আটকে থাকতে হবে কারণ এসকিউএল সার্ভার 2005 এর জন্য সমর্থন প্রয়োজন। তবে আমি ভবিষ্যতের প্রকল্পগুলির জন্য এটি মাথায় রাখব। ধন্যবাদ!
লুই সোমার

3
উজ্জ্বল, এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
ক্রিস ময়ূর

3
আশা করি এটি ডিবিএ স্ট্যাকেক্সচেঞ্জের পরিবর্তে স্ট্যাকওভারফ্লোতে ছিল। এটির দৃশ্যমানতা খুব কম। আশ্চর্যজনক উত্তর।
লর্ডবালমন

3
প্রথম চেষ্টা থেকে কব্জির মতো কাজ করেছেন ... দুর্দান্ত উত্তর!
বিমেরগুই

5

আউটপুট ধারাটি কেবল লক্ষ্য সারি এবং ধ্রুবক / ভেরিয়েবলগুলিতে ডেটা অ্যাক্সেস করতে পারে, উত্সের অন্য কোথাও থেকে ডেটা নয় SELECT, যেমন আপনি যদি ট্রিগারটিতে কাজ করে থাকেন তবে ।

https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql বলে:

সারণীতে কলামগুলির যে কোনও রেফারেন্স সংশোধন করা হচ্ছে অবশ্যই সন্নিবেশিত বা মুছে ফেলা উপসর্গের সাথে যোগ্যতা অর্জন করতে হবে।

আসল আইডিটি পেতে আপনাকে এটিকে গন্তব্য সারণিতে অন্তর্ভুক্ত করতে হবে যাতে আউটপুট ধারাটি এটি আবার প্রতিধ্বনি করতে পারে:

-- The existing table 
DECLARE @MyTable TABLE (ID INT IDENTITY(1,1), [Name] NVARCHAR(MAX), SourceID INT);

-- My data I want to insert
DECLARE @MyInsertData TABLE (ID INT, [Name] NVARCHAR(MAX));
INSERT INTO @MyInsertData ( ID,Name)
VALUES ( -1 , 'bla'),(-2,'test'),(-3,'last');

DECLARE @MyCrossRef TABLE ([NewId] INT, OldId INT);

INSERT INTO @MyTable ( [Name], SourceID )
   OUTPUT Inserted.ID, Inserted.SourceID INTO @MyCrossRef
   SELECT [NAME], ID FROM @MyInsertData INS

-- Check the result
SELECT * FROM @MyCrossRef

যদিও লক্ষ্য অবজেক্টের স্কিমা পরিবর্তন করা আপনার পরিস্থিতিতে ব্যবহারিক নাও হতে পারে তাই এটি প্রযোজ্য নাও হতে পারে।


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