2017-05-30 54 views
-1

我有一個包含三列的SQL Server表,前兩列是主鍵。我正在編寫一個存儲過程,它將更新最後兩列的大小,只要沒有主鍵違規,但是當存在主鍵違例時,它會拋出錯誤並停止執行。使用組合鍵更新SQL Server表

只要沒有主鍵違規,我怎樣才能讓它忽略該行並繼續更新記錄?

有沒有更好的方法來解決這個問題?我只做了一個簡單的更新,其中column2 = somevalue AND column 3 = some value。

+0

MSQL代表什麼? mSQL的?或者這是MySQL的錯字?或者你的意思是Microsoft SQL Server?你正在尋找的是俗稱的upsert,並且語法不同,從一個DBMS到另一個。 –

+0

對不起,我的意思是Microsoft SQL。我不確定Microsoft Sql的縮寫是什麼 – Tex

+0

微軟有兩個DBMS(AFAIK):MS Access和SQL Server。我想你是指SQL Server? –

回答

0

在SQL Server中,你會使用MERGE到UPSERT(即插入或更新):

MERGE mytable 
USING (SELECT 1 as key1, 2 as key2, 3 as col1, 4 as col2) AS src 
    ON (mytable.key1 = src.key1 AND mytable.key2 = src.key2) 
WHEN MATCHED THEN 
    UPDATE SET col1 = src.col1, col2 = src.col2 
WHEN NOT MATCHED THEN 
    INSERT (key1, key2, col1, col2) VALUES (src.key1, src.key2, src.col1, src.col2); 
+0

謝謝。我明天會試試,並讓你知道。我不確定你爲什麼使用插入,因爲我沒有試圖插入新記錄,但只有在已經存在的情況下才更新。 – Tex

+0

對不起,你是對的。我誤解了你的問題。您只是更新,但您正在更新*主鍵*。所以請忽略這個答案。我將在稍後刪除它。至於你在做什麼:*從不*更新主鍵。它意味着在其生命週期中識別一行。如果你認爲你必須更新它,這很可能是一個糟糕的數據庫設計的標誌。 –

0

沒有什麼內在的錯誤你的問題,儘管相當響亮抗議。你的問題很混亂,特別是當你按位置提及各列時。這是一個很大的禁忌。因此,演示您的問題的腳本通常是展示您的問題並獲得有用建議的最佳方式。

你的問題的簡短答案是 - 你不能。聲明要麼整體成功要麼失敗。如果你想單獨更新每一行並忽略某些錯誤,那麼你需要編寫你的tsql來做到這一點。

儘管出現了抗議(再次),但在某些情況下需要更新作爲主鍵一部分的列。這是不尋常的 - 很不尋常 - 但你也應該警惕任何有關tsql的絕對聲明。當你發現自己在做不尋常的事情時,應該審查你的模式(和你的方法),因爲很可能有更好的方法來實現你的目標。

而在這種情況下,我建議你SHOULD真的想着你想要完成什麼。如果您想以特定方式更新一組行,並且語句失敗 - 這意味着某處存在缺陷!通常,這個錯誤意味着你的更新邏輯不正確。也許你假設你的數據不準確?從遠處知道是不可能的。錯誤信息會告訴你哪些值導致了衝突 - 所以應該給你足夠的信息來進行調查。作爲另一個工具,編寫一個選擇語句來演示您提出的更新並查找錯誤消息中的值。例如。

set nocount on; 
create table #x (a smallint not null, b smallint not null, c varchar(10) not null, constraint xx primary key(a, b)); 

insert #x (a, b, c) values (1, 1, 'test'), (1, 2, 'zork'); 
select * from #x; 

update #x set b = 2, c = 'dork'; 

select a, b, c, cast(2 as smallint) as new_b, 'dork' as new_c 
from #x 
order by a, new_b; 

drop table #x;