2012-03-26 66 views
0

比方說,我有兩個表外鍵關聯TSQL插入數據

RDB_DataEntities

DataEntityId 
Name 
Created 
Modified 
... 

RDB_DataInstances

DataInstanceId 
DataEntityId 

所以RDB_DataInstances通過外鍵連接到RDB_DataEntities在他們的DataEntityId列。

比方說,我想將數據插入到在同一事務兩個表。我對這個過程的代碼如下:

using (var con = new SqlConnection("data source=speedy;initial catalog=mydb;user id=myuser;password=mypass")) 
{ 
    con.Open(); 

    using (var tran = con.BeginTransaction()) 
    { 
     SqlCommand i1 = new SqlCommand("insert into RDB_DataEntities (Name,IsSchema,Created,Modified,RequireCaptcha,UniqueByEmail,UniqueByMac) values ('hi',0,GetDate(),GetDate(),0,0,0)", con, tran); 

     i1.ExecuteNonQuery(); 

     SqlCommand i2 = new SqlCommand("select SCOPE_IDENTITY() as newid", con, tran); 
     var id = int.Parse(i2.ExecuteScalar().ToString()); 

     SqlCommand i3 = new SqlCommand("insert into RDB_DataInstances (DataEntityId) values (" + id + ")", con, tran); 
     i3.ExecuteScalar(); 
     tran.Commit(); 
    } 
} 

爲什麼會拋出一個外鍵錯誤

INSERT語句衝突與外鍵約束 「FK_RDB_DataInstances_RDB_DataEntities」。衝突發生在 數據庫'NMSS_CMS',表'dbo.RDB_DataEntities', 'DataEntityId'列中。

事務不應該知道我插入的外鍵基於插入我只是在當前事務上下文中做的?我離開嗎?

你如何做到這一點?

+0

它沒有發生在你的第一個'INSERT'上嗎?也就是說,你沒有設置FK的方式是錯誤的... – 2012-03-27 03:41:49

回答

1

因爲當你使用兩個不同的命令上下文(定義上講,它是一個獨立的範圍)SCOPE_IDENTITY()將無法​​正常工作。你可以追加第二查詢到第一,並運行ExecuteScalar(),就像這樣:

SqlCommand i1 = new SqlCommand("insert into RDB_DataEntities (Name,IsSchema,Created,Modified,RequireCaptcha,UniqueByEmail,UniqueByMac) values ('hi',0,GetDate(),GetDate(),0,0,0);select SCOPE_IDENTITY() as newid;",con,tran);     
var id=int.Parse(i1.ExecuteScalar().ToString()); 

編輯:只是想扔在一起,這是怎麼回事的T-SQL版本。

DECLARE @newid int 

BEGIN TRANSACTION 

insert into RDB_DataEntities 
    (Name,IsSchema,Created,Modified,RequireCaptcha,UniqueByEmail,UniqueByMac) 
values 
    ('hi',0,GetDate(),GetDate(),0,0,0) 

SELECT @newid = SCOPE_IDENTITY() 

insert into RDB_DataInstances 
    (DataEntityId) 
values 
    (@newid) 

COMMIT TRANSACTION 
+2

另一種解決方案:使用輸出子句。保存查詢。 – 2012-03-26 20:53:41

+0

SCOPE_IDENTITY()明確地適用於兩種方式。我調試過,以確保我的var id肯定有一個整數值。 – Micah 2012-03-26 20:55:12

+0

如果你正在獲得正確的價值,那麼我同意它應該起作用。你正在嘗試做的T-SQL版本是合乎邏輯的。 – mgnoonan 2012-03-26 21:02:19

0

下面是你2個可能的解決方案,如果我理解你的問題:

  1. 您可以設置事務隔離級別,並使用READ UNCOMMITTED/NOLOCK對先前插入執行髒讀記錄在交易中(看到這篇文章的更多Why use a READ UNCOMMITTED isolation level?

  2. 您可以在代碼中創建Guid並手動插入到2個表中作爲SqlCommand參數,而不是使用後SCOPE_IDENTITY()第一次插入。 (我的首選選項)

0

我放棄了外鍵並重新創建它並開始工作。