我使用.NET 2.0運行MS SQL Server 2005。我目前的應用程序是用C#編寫的。使用自動生成的更新從ADO.NET級聯更新存儲過程
在MSSQL中,我創建2個測試表來說明我的問題:
表1是設置爲:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[T1](
[n] [bigint] NOT NULL,
[t] [varchar](10) NOT NULL,
CONSTRAINT [PK_T1] PRIMARY KEY CLUSTERED
(
[n] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
表2是設置爲:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[T2](
[n] [bigint] NULL,
[Test] [varchar](4) NOT NULL,
[Num] [bigint] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[T2] WITH CHECK ADD CONSTRAINT [FK_T2_T1] FOREIGN KEY([n])
REFERENCES [dbo].[T1] ([n])
ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[T2] CHECK CONSTRAINT [FK_T2_T1]
我已經每個行填充了多行。
簡而言之,表1(T1)具有映射到子表T2的n字段的bigint主鍵字段「n」。級聯更新設置爲當T1.n被修改時,則T2.n也被更新。如果我做了一個簡單的查詢,並在其中一行中設置了T1.n的值,我可以看到執行計劃中出現了級聯。如果我設置了T1.t的值,級聯不會像預期的那樣出現在執行計劃中。
在ADO.NET我已經添加了一個DataAdapter到我的形式,把它自動生成4個存儲過程,更新出現T1如下:(我加了一些空間,以幫助可讀性)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[T1_Update]
(
@n bigint,
@t varchar(10),
@Original_n bigint,
@Original_t varchar(10)
)
AS
SET NOCOUNT OFF;
UPDATE [T1]
SET
[n] = @n,
[t] = @t
WHERE (
([n] = @Original_n) AND
([t] = @Original_t));
SELECT n, t FROM T1 WHERE (n = @n)
我可以執行這個存儲過程:
DECLARE @RC int
DECLARE @n bigint
DECLARE @t varchar(10)
DECLARE @Original_n bigint
DECLARE @Original_t varchar(10)
EXECUTE @RC = [T1_Update]
5, '5', 5, '4' -- n, t, Original_n, Original_t
這樣n的值就不會改變,t的值也會改變。我期望看到相同的行爲/執行計劃,就好像我剛剛做了「UPDATE T1 SET t ='4',其中n = 5和t ='5'」。運行此查詢時,執行計劃非常簡單,只需執行CI查找,計算標量,CI更新,更新。
但是,執行上面的執行計劃顯示它掃描表T2並在所述表上執行更新,即使該值未被更改。
我認爲這是由於這樣的線:
UPDATE [T1]
SET
[n] = @n,
注出從T1_Update存儲過程中[η] = @n,即使值不改變,停止級聯更新從擊發。
因此,假設我想保持級聯更新,是否有重寫/修改自動生成的T1_Update存儲過程的方法,以便級聯更新僅在「n」的值發生更改時才激活,價值不變?
編輯:我刪除了T1上的一個外鍵關係,它引用了我在設置此測試時意外添加的內容。
瞭解並且我們目前正在重新評估之前設計到數據庫中的所有Cascade更新以刪除它們。起初它被認爲是級聯更新不會傷害事情,如果關鍵是真的不變,級聯不會觸發。但是我們發現,自動生成的更新過程被調用,即使該值沒有變化,它也會「更改」該值。所以我想弄清楚爲什麼這個級聯發生在第一位,以及如何避免它。仍然困惑於爲什麼它是級聯的。 – Equixor 2010-11-03 00:24:06
@Equixor:剛剛注意到了一些事情 - 爲什麼T1.n上有一個外鍵,它指向T1.n?那就是,這個領域是指自己? ???我從來沒有見過這樣做過。 – 2010-11-03 11:06:00
當我添加對測試的引用時,我必須在T1上添加關係並點擊關閉。按下添加後,如果沒有修改,它不會自動刪除它,並且默認是對自身的引用(這是無用的)。我刪除了這個引用,因爲它顯然不是必需的,級聯行爲不受影響。 – Equixor 2010-11-03 18:17:53