كيفية إدراج سجلات متعددة والحصول على قيمة الهوية؟

أقوم بإدراج عدة سجلات في جدول A من جدول آخر B. هل هناك طريقة للحصول على قيمة الهوية لسجل الجدول A وتحديث سجل الجدول b بدون القيام بمؤشر؟

Create Table A
(id int identity,
Fname nvarchar(50),
Lname nvarchar(50))

Create Table B
(Fname nvarchar(50),
Lname nvarchar(50),
NewId int)

Insert into A(fname, lname)
SELECT fname, lname
FROM B

أنا أستخدم MS SQL Server 2005.

0
وأضاف تحرير
الآراء: 5
الجواب اندي ايرفينغ هو الأفضل. المشغلات هي خرقاء ولا تعمل بشكل جيد لعمليات عشوائية على الطاولة المستهدفة ، خاصة إذا كان هدفك مؤقتًا أو مجرد وسيط. إجابة دارين خاطئة ، إذا كنت تقوم بإدخال مجموعة من الصفوف ، فإن ترتيبها في الجدول المستهدف ليس بالضرورة مطابقًا لترتيب المجموعة. طريقة ديمتري سيئة لأنها تتطلب حلقة حول إدخال صف واحد في وقت بطيء الأداء ، استخدم دائما مجموعات عندما تستطيع. طريقة كوري سيئة وفسر لماذا "طالما أنها لا تتعارض". هذا سوف يتحول إلى ليلة السبت ج
وأضاف المؤلف clemahieu, مصدر
أدرك أن هذا سؤال قديم ويحدد SQL Server 2005 ولكن بما أنه أول نتيجة لعرض بيان MERGE المتوفر في عام 2008 ويجب ذكره لاحقًا لأولئك الذين يبحثون عن حل. دمج في TargetTable باستخدام (SELECT ....) AS Source ON 1 = 2 عندما لا يتم التضمين فيه INSERT .... OUTPUT inserted.ID INTO TempTable (InsertedID)
وأضاف المؤلف oldegreyg, مصدر
لا تحتاج إلى دمج لإدخال بسيط. الدمج جيد لإدخال/تحديث ، ولكن مبالغة لإدراج بسيطة في. عملت إجابة الإخراج اندي بالنسبة لي وساعدت على سحب قفل مؤشر.
وأضاف المؤلف CodeMonkeyForHire, مصدر

7 إجابة

يمكنك الحصول على الاشتراك من خلال الانضمام إلى رقم الصف . هذا ممكن لأنه لأنه هوية ، فإنه سيزداد بمجرد إضافة العناصر ، والتي ستكون بالترتيب الذي تقوم بتحديده.

0
وأضاف
خطأ ، السجلات غير مضمونة للذهاب إلى قاعدة البيانات في الترتيب الذي تعتقد أنهم ذاهبون فيه.
وأضاف المؤلف HLGEM, مصدر

بقدر ما أفهمها ، المشكلة التي تواجهها هي أنك تريد إدراج في جدول A ، الذي يحتوي على عمود هوية ، وتريد الحفاظ على الهوية من الجدول B الذي لا.

من أجل القيام بذلك ، يجب عليك فقط تشغيل إدخال الهوية في الجدول A. سيسمح لك ذلك بتعريف المعرّف الخاص بك على الإدخال ، وطالما لا تتعارض ، يجب أن تكون على ما يرام. ثم يمكنك فقط القيام بما يلي:

Insert into A(identity, fname, lname) SELECT newid, fname, lname FROM B

لست متأكدًا من قاعدة البيانات التي تستخدمها ولكن بالنسبة إلى خادم SQL ، سيكون أمر تشغيل إدخال الهوية هو:

set identity_insert A on
0
وأضاف
إنه لا يحاول تحديث الجدول A ، إنه يحاول تحديث الجدول B. لا يحتوي الجدول B على عمود هوية.
وأضاف المؤلف njr101, مصدر

إذا كنت تقرأ سؤالك بعناية ، فأنت تريد فقط تحديث الجدول B بناءً على قيم الهوية الجديدة في الجدول A.

بعد الانتهاء من الإدراج ، قم بتشغيل تحديث ...

UPDATE B
SET NewID = A.ID
FROM B INNER JOIN A
     ON (B.FName = A.Fname AND B.LName = A.LName)

هذا يفترض أنه يمكن استخدام تركيبة FName/LName لمطابقة السجلات بين الجداول. إذا لم تكن هذه هي الحالة ، فقد تحتاج إلى إضافة حقول إضافية للتأكد من مطابقة السجلات بشكل صحيح.

إذا لم يكن لديك مفتاح بديل يسمح لك بمطابقة السجلات ، فهذا ليس منطقيًا على الإطلاق ، حيث لا يمكن تمييز السجلات الموجودة في الجدول ب عن بعضها البعض.

0
وأضاف

MBelly على المال مباشرة - لكن المحفز سيحاول دائمًا تحديث الجدول B حتى إذا لم يكن ذلك مطلوبًا (لأنك أيضًا تدخل من الجدول C؟).

دارين صحيح هنا ، لا يمكنك الحصول على هويات متعددة مرة أخرى كمجموعة نتائج. تستخدم خياراتك المؤشر وتتخذ هوية كل صف تدخله ، أو تستخدم أسلوب دارين في تخزين الهوية قبلها وبعدها. طالما أنك تعرف زيادة الهوية ، يجب أن يعمل هذا ، طالما أنك تتأكد من تأمين الجدول لجميع الأحداث الثلاثة.

إذا كنت أنا ، ولم يكن الوقت حرجًا سأذهب مع المؤشر.

0
وأضاف

إذا كنت تريد هذا السلوك دائمًا ، يمكنك وضع مشغل AFTER INSERT على TableA الذي سيقوم بتحديث الجدول ب.

0
وأضاف

أقترح استخدام نوع uniqueidentifier بدلاً من الهوية. في هذه الحالة ، يمكنك إنشاء معرّفات قبل الإدراج:

update B set NewID = NEWID()

insert into A(fname,lname,id) select fname,lname,NewID from B
0
وأضاف

استخدم جملة ouput من 2005:

DECLARE @output TABLE (id int)

Insert into A (fname, lname)
OUTPUT inserted.ID INTO @output
SELECT fname, lname FROM B

select * from @output

الآن يحتوي متغير الجدول الخاص بك على قيم هوية جميع الصفوف التي تقوم بإدخالها.

0
وأضاف
munissor ، أعرف أن هذا خيط قديم ، ولكن راجع هذه المقالة حول الحديث البسيط حول هذا الموضوع. انظر إلى القسم "إضافة جملة OUTPUT".
وأضاف المؤلف Mr Moose, مصدر
لاحظ أن هذا فشل فشلاً ذريعاً عندما يحتوي الجدول A على مشغل ، بسبب خطأ ترفض Microsoft إصلاحه. هناك حل آخر هنا: stackoverflow.com/q/13198476/2557263
وأضاف المؤلف Alejandro, مصدر
munissor متأخر بعض الشيء ولكن يمكنك فعله إخراج inserted.id ، inserted.whateverColumn فيoutput
وأضاف المؤلف Dennis Rongo, مصدر
ولكن كيف تقوم بتحديث الجدول ب؟ أعني ، كيف تربط كل سجل لـoutput بسجل في B؟ إذا كنت تستخدم fname ، lname كمفتاح ، فمن الأسهل استخدام حل njr.
وأضاف المؤلف munissor, مصدر
DennisRongo فقط إذا كان inserted.whateverColumn هو معرف فريد آخر ...
وأضاف المؤلف Mark, مصدر