我繼承了我需要處理的 SQL 代碼,其設定類似于以下內容:
CREATE TABLE [dbo].[Ni](
[FooID] [int] IDENTITY(1,1) NOT NULL,
[Bar] [nvarchar](60) NULL,
[LocationID] [int] NULL,
[Thing1] [float] NULL
CONSTRAINT [PK_Ni] PRIMARY KEY CLUSTERED
(
[FooID] ASC
);
CREATE UNIQUE NONCLUSTERED INDEX [UQ_LocationBar] ON [dbo].[Ni]
(
[LocationID] ASC,
[Bar] ASC
);
CREATE TABLE [dbo].[Ni_Two](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FooID] [int] NOT NULL,
[Thing2] [int] NOT NULL,
[Thing3] [int] NOT NULL
CONSTRAINT [PK_Ni_Two] PRIMARY KEY CLUSTERED
(
[ID] ASC
);
ALTER TABLE [dbo].[Ni_Two] WITH CHECK ADD CONSTRAINT [FK_NiTwo_FooID] FOREIGN KEY([FooID])
REFERENCES [dbo].[Ni] ([FooID]);
CREATE TABLE [dbo].[KillMe](
[ID] [int] NOT NULL,
[FooID] [int] NULL,
[Thing4] [int] NOT NULL,
[Thing5] [int] NOT NULL
PRIMARY KEY CLUSTERED
(
[ID] ASC
);
ALTER TABLE [dbo].[KillMe] WITH NOCHECK ADD CONSTRAINT [FK_KillMe_FooID] FOREIGN KEY([FooID])
REFERENCES [dbo].[Ni] ([FooID]);
CREATE TABLE [dbo].[PleaseStop](
[ID] [int] NOT NULL,
[KillMeID] [int] NOT NULL,
[Thing7] [int] NOT NULL,
[Thing8] [int] NOT NULL
PRIMARY KEY CLUSTERED
(
[Id] ASC
);
ALTER TABLE [dbo].[PleaseStop] WITH CHECK ADD CONSTRAINT [FK_PleaseStop_KillMe] FOREIGN KEY([KillMeID])
REFERENCES [dbo].[KillMe] ([ID]);
問題在于,這種設計與[Ni].dbo.[Bar]. 這個獨特的約束是作為一個要求放在那里的。每個FooID都是唯一的,每個Bar分配給的都LocationID必須是唯一的。
現在要求發生了變化。每個季度匯入都會有一些條目Bar必須更新該欄位。
我努力了:
UPDATE dbo.[Ni]
SET Bar = Imp.Bar
, LocationID = Imp.LocationID
, Thing1 = Imp.Thing1
FROM dbo.[Ni]
INNER JOIN ImportData Imp ON [Ni].FooID = Imp.FooID
這會給我一個Violation of UNIQUE KEY constraint錯誤。
我不想更改架構,因為我不知道它會對代碼產生什么其他影響。該程式的作者已經離開了公司。. . 我在這里。
作為維護例程的一部分,該程式每季度運行一次(IE 一年四次)。
我可以在不使用WHILE陳述句的情況下做到這一點嗎?因為那會很痛苦。
謝謝!
uj5u.com熱心網友回復:
所以要么在一個查詢中更新它們,例如
CREATE TABLE [dbo].[Ni](
[FooID] [int] IDENTITY(1,1) NOT NULL,
[Bar] [nvarchar](60) NULL,
[LocationID] [int] NULL,
[Thing1] [float] NULL
CONSTRAINT [PK_Ni] PRIMARY KEY CLUSTERED
(
[FooID] ASC
)
);
CREATE UNIQUE NONCLUSTERED INDEX [UQ_LocationBar] ON [dbo].[Ni]
(
[LocationID] ASC,
[Bar] ASC
);
insert into Ni(bar) values ('a'),('b'),('c');
with newValues as
(
select * from (values (1,'c'),(3,'x')) newValues (FooId, Bar)
),
toUpdate as
(
select ni.FooId, ni.Bar, NewValues.Bar NewBar
from Ni
join NewValues
on ni.FooID = newValues.FooId
)
update toUpdate set Bar = NewBar
或禁用并重建唯一索引
begin transaction
alter index [UQ_LocationBar] on ni disable
update ni set bar = 'b' where fooid = 1
update ni set bar = 'a' where fooid = 2
alter index [UQ_LocationBar] on ni rebuild
commit transaction
我是否允許在存盤程序中禁用和重新啟用約束?
當然,它需要額外的權限,但在存盤程序中運行 DDL 沒有任何限制,并且在 SQL Server 中,DDL 是完全事務性的,因此您可以提交/回滾以防止部分更新并防止其他會話看到部分結果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/446841.html
