הוספת שורות לשתי טבלאות בו זמנית

01/12/2016

אין תגובות

פעם כתבתי פוסט על הנושא, בעיקר בתור אתגר; בשם חסכו ואמצו (2).
באופן כללי, ניתן לשלוף את השורות שהשתנו (במקרה זה – התווספו) על ידי האופרטור Output,
ואם קצת מתחכמים – להפנות את הפלט של ה-Output לטבלה שניה.
בערך כך:

If        Object_ID('B') Is Not Null

        Drop Table B;

 

If        Object_ID('A') Is Not Null

        Drop Table A;

 

Create Table A(ID Int Identity Primary Key,

            Txt Varchar(10));

 

Create Table B(ID Int Identity Primary Key,

            IDA Int);

 

Insert

Into    B(IDA)

Select    ID

From    (Insert

        Into    A(Txt)

        Output    Inserted.*

        Values    ('a'),

                ('bb')) T;

 

Select * From A;

Select * From B;

image

מה קורה אם יש Foreign Key בין שתי הטבלאות?

Alter Table B Add Constraint [FK_B_IDA] Foreign Key (IDA) References A (ID);

כעת פעולת ה-Insert הכפולה תיכשל:

image

בשל קיום ה-Foreign Key בטבלה “החיצונית” (כלומר – זו שב-Insert שמחוץ לסוגריים) זה לא יצליח. כלומר, גם אם נחליף את טבלה A בטבלה שאינה חלק מיחסי ה-Foreign Key – ה-Insert הכפול יכשל, כי B כן קשורה ב-Foreign Key לטבלה אחרת. מנגד, אם נחליף את B בטבלה לא קשורה – הבעייה תיפתר.
מי שמתעקש, יכול לעקוף את המגבלה הנ”ל על ידי שימוש ב-SQL דינאמי:

Insert

Into    B(IDA)

Exec(    N'Insert

        Into    A(Txt)

        Output    Inserted.ID

        Values    (''a''),

                (''bb'');');

 

Select * From A;

Select * From B;

image

הפלט כולל גם את 2 השורות מהריצה הראשונה.

דוגמה אחרת, עם משתנה טבלה: ניצור מחדש את הטבלאות, ו-Table Type:

If        Object_ID('B') Is Not Null

        Drop Table B;

 

If        Object_ID('A') Is Not Null

        Drop Table A;

 

If        Exists (Select * From sys.types Where name='Tbl')

        Drop Type Tbl;

 

Create Table A(ID Int Identity Primary Key,

            Txt Varchar(10));

 

Create Table B(ID Int Identity Primary Key,

            IDA Int);

 

Alter Table B Add Constraint [FK_B_IDA] Foreign Key (IDA) References A (ID);

 

Create    Type dbo.Tbl As Table(Txt Varchar(10));

וכעת נשתמש ב-sp_executesql כדי להעביר את הפרמטר לקוד הדינאמי:

Declare    @T Tbl;

Insert

Into    @T

Values    ('a'),

        ('bb');

 

Insert

Into    B(IDA)

Exec    sp_executesql N'Insert

        Into    A(Txt)

        Output    Inserted.ID

        Select    *

        From    @T1;',

        N'@T1 Tbl ReadOnly',

        @T1=@T;

 

Select * From A;

Select * From B;

image

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *