SQL Server:هل من الممكن أن تضاف إلى الجدولين في نفس الوقت ؟

StackOverflow https://stackoverflow.com/questions/175066

سؤال

قاعدة البيانات تحتوي على ثلاثة جداول تسمى Object_Table, Data_Table و Link_Table.رابط الجدول يحتوي على عمودين ، هوية كائن سجل هوية من سجل البيانات.

أريد أن نسخ البيانات من DATA_TABLE حيث يرتبط أحد كائن معين الهوية إدراج السجلات في المقابلة Data_Table و Link_Table من أجل إعطاء هوية الكائن.

أنا يمكن القيام بذلك عن طريق اختيار في الجدول متغير حلقات من خلال القيام اثنين إدراج كل التكرار.

هذا هو أفضل طريقة للقيام بذلك ؟

تحرير :أريد أن تجنب حلقة اثنين السبب الأول هو أنني كسول حلقة/temp الجدول يتطلب المزيد من رمز رمز أكثر يعني المزيد من الأماكن بخطأ و السبب الثاني هو القلق حول الأداء.

لا يمكن نسخ جميع البيانات في إدراج ولكن كيف تحصل على رابط الجدول على الرابط الجديد سجلات البيانات حيث يحتوي كل سجل جديد معرف ؟

هل كانت مفيدة؟

المحلول 3

التالية مجموعات يصل الوضع كان باستخدام متغيرات الجدول.

DECLARE @Object_Table TABLE
(
    Id INT NOT NULL PRIMARY KEY
)

DECLARE @Link_Table TABLE
(
    ObjectId INT NOT NULL,
    DataId INT NOT NULL
)

DECLARE @Data_Table TABLE
(
    Id INT NOT NULL Identity(1,1),
    Data VARCHAR(50) NOT NULL
)

-- create two objects '1' and '2'
INSERT INTO @Object_Table (Id) VALUES (1)
INSERT INTO @Object_Table (Id) VALUES (2)

-- create some data
INSERT INTO @Data_Table (Data) VALUES ('Data One')
INSERT INTO @Data_Table (Data) VALUES ('Data Two')

-- link all data to first object
INSERT INTO @Link_Table (ObjectId, DataId)
SELECT Objects.Id, Data.Id
FROM @Object_Table AS Objects, @Data_Table AS Data
WHERE Objects.Id = 1

بفضل آخر الجواب الذي أشار لي نحو إخراج شرط لا يمكن إظهار الحل:

-- now I want to copy the data from from object 1 to object 2 without looping
INSERT INTO @Data_Table (Data)
OUTPUT 2, INSERTED.Id INTO @Link_Table (ObjectId, DataId)
SELECT Data.Data
FROM @Data_Table AS Data INNER JOIN @Link_Table AS Link ON Data.Id = Link.DataId
                INNER JOIN @Object_Table AS Objects ON Link.ObjectId = Objects.Id 
WHERE Objects.Id = 1

اتضح أن الأمر ليس بهذه البساطة في الحياة الحقيقية بسبب الخطأ التالي

الإخراج إلى شرط لا يمكن على جانبي (المفتاح الأساسي الخارجية ، مفتاح) العلاقة

لا يزال يمكنني OUTPUT INTO مؤقت الجدول ومن ثم إنهاء طبيعية مع إدراج.لذا يمكن تجنب حلقة بلدي ولكن أنا لا يمكن تجنب الجدول المؤقت.

نصائح أخرى

في واحد بيان:لا.

في واحد الصفقة:نعم

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

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

كنت لا تزال بحاجة اثنين INSERT البيانات, ولكن هذا يبدو وكأنه كنت ترغب في الحصول على IDENTITY من أول إدراج في الثانية ، وفي هذه الحالة ، قد ترغب في النظر في OUTPUT أو OUTPUT INTO: http://msdn.microsoft.com/en-us/library/ms177564.aspx

يبدو أن الرابط الجدول يلتقط العديد من:العديد من علاقة بين كائن جدول البيانات في الجدول.

اقتراحي هو استخدام إجراء مخزن لإدارة المعاملات.عندما تريد إدراج كائن أو جدول البيانات الخاص بك أداء إدراج الحصول على بطاقات هوية جديدة وإدراجها في رابط الجدول.

هذا يسمح كل من المنطق أن تظل مغلفة في واحدة سهلة الاتصال sproc.

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

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

أريد أن أؤكد على استخدام

SET XACT_ABORT ON;

بالنسبة MSSQL المعاملة مع عدة عبارات sql.

انظر: https://msdn.microsoft.com/en-us/library/ms188792.aspx أنها توفر مثال جيد جدا.

لذا النهائي رمز يجب أن تبدو كما يلي:

SET XACT_ABORT ON;

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

إدراج يمكن أن تعمل فقط على طاولة واحدة في وقت واحد.تدرج متعددة يكون لديك بيانات متعددة.

أنا لا أعرف أن كنت بحاجة إلى القيام به حلقات من خلال الجدول متغير - لا يمكنك فقط استخدام كتلة تضاف الى طاولة واحدة ، ثم كتلة تضاف إلى الآخر ؟

بالمناسبة انا التخمين كنت تقصد نسخ البيانات من Object_Table;وإلا فإن السؤال لا معنى له.

قبل أن تكون قادرة على القيام multitable إدراج في أوراكل ، يمكنك استخدام خدعة التي تتضمن إدراج في عرض هذا بدلا من أن تؤدي إلى المعرفة على أنها لأداء إدراج.يمكن أن يتم ذلك في SQL Server?

-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE InsetIntoTwoTable

(
@name nvarchar(50),
@Email nvarchar(50)
)

AS
BEGIN

    SET NOCOUNT ON;


    insert into dbo.info(name) values (@name)
    insert into dbo.login(Email) values (@Email)
END
GO

//إذا كنت ترغب في إدراج نفس الجدول الأول

$qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";

$result = @mysql_query($qry);

$qry2 = "INSERT INTO table2 (one,two, three) VVALUES('$one','$two','$three')";

$result = @mysql_query($qry2);

//أو إذا كنت ترغب في إدراج أجزاء معينة من جدول واحد

 $qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";


  $result = @mysql_query($qry);

 $qry2 = "INSERT INTO table2 (two) VALUES('$two')";

 $result = @mysql_query($qry2);

//أعرف أن الأمر يبدو جيدا جدا ليكون صحيح ، لكنه يعمل و يمكنك الحفاظ على إضافة الاستعلام فقط تغيير

    "$qry"-number and number in @mysql_query($qry"")

لدي 17 الجداول هذا وقد عملت في.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top