2016-04-28 75 views
1

我試圖更新我們的系統中的患者表,但由於我們與將狀態發送到外部系統的狀態發生連接,因此無法進行大規模更新我們的系統中有幾個觸發器(Microsoft SQL Server 2008 R2)。在觸發代碼的主要一塊是防止無法單獨更新行

IF (@numrows > 1) 
BEGIN 
    IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION 
    SELECT @errmsg = OBJECT_NAME(@@PROCID) + ' : more than one row is updated in table Patient'         
    RAISERROR(@errmsg,16,21) 
    RETURN 
END 

我不能簡單地關閉這些激發了它會打破了很多東西,所以做什麼會是

update patient set security_level = '2' 
where security_level = '1' 
一個簡單的動作

我用下面的代碼,在使用以前版本

declare @tmp_table table(
PRG int identity(1,1) Primary Key, 
patient_id int 
) 

declare @start_value int = 1, 
@finish_value int, 
@patient_id int 

Insert Into @tmp_table(patient_id) Select patient_id From patient where security_level = '1' 

Select @finish_value = max(PRG) From @tmp_table 

While @start_value <= @finish_value 
Begin 
    --now get a key for patient and store in variables 
    Select @patient_id = patient_id 
    From @tmp_table 
    Where PRG = @start_value 

    --.. and now update by key 
    Update patient 
    set security_level = '2' 
    Where patient_id = @patient_id 


Set @start_value = @start_value + 1 
End 

工作,我得到運行時的代碼

以下錯誤

消息50000,級別16,狀態21,過程tU_Patient_HL7,行64
tU_Patient_HL7:多個行於表病人更新

消息3609,級別16,狀態1,行22
事務在觸發器中結束。該批次已被中止。

任何想法如何我可以調整此或重新編碼此更新安全級別設置爲1的所有患者的安全級別並將其切換到2?

更新 會不會有什麼辦法,我可以循環

Update top (1) patient 
set security_level = '2' 
where security_level = '1' 

直到所有的行會受到影響?那也可以。

+0

哇停止批量更改到表的觸發器。這味道真的很糟糕。無論如何....你能確認'patient.patient_id'是一個主鍵還是唯一約束呢?如果不是那種味道更糟。 –

+0

Patient_id是主鍵。開發者告訴我他們以這種方式設置的原因在於它向人口狀態發送人口統計信息,但發送事務的Java小程序無法發送大量更改。 –

+0

開發人員認爲這不是一個好主意。無論如何,我不明白這裏的全部故事 –

回答

1

擁有了完整的代碼,這是很難。我猜你的更新語句下面的代碼peice的相互衝突..

IF(@numrows> 1)

即使您使用

Update patient 
    set security_level = '2' 
    Where patient_id = @patient_id 

你的更新查詢可能會影響不止一個row.So我最好的選擇將是調整你的更新查詢低於或改變觸發如果可以的話這是希望的

Update top (1) patient 
    set security_level = '2' 
    Where patient_id = @patient_id 
+0

它肯定是觸發器導致問題的IF(@numrows> 1),但如果我改變它,很多事情都會中斷。我可以做個人更新,但我有大約200個更新,所以我希望有一種方法,我可以讓它更新200,但延遲每次更新之間的時間或某事,所以它會讓它通過。 –

+0

更新頂部是一種更快的方式,可以通過手動進行1 1操作。 –

+0

在一個循環中更新200行將非常快(沒有任何理由在延遲時間 - 它不會像那樣工作)。但是'@ numrows'觸發器會削弱基本的數據庫功能(批量數據更改),您真的需要考慮它爲什麼存在以及如何永久刪除它。這是一個壞主意,它聞起來像有人不明白觸發器 –

1

如果你添加到你的更新代碼中的「GO 100」,那應該可以做到。如果觸發器的更新速度過快,您可能還需要延遲。

Update top (1) patient 
set security_level = '2' 
where security_level = '1' 
GO 100 

執行次數(在我的例子中爲100)取決於你。

+0

我們對一些客戶端服務器有類似的限制,我們只能一次更新一些安全設置。進行這些更改需要更長的時間,但無論是好還是壞,客戶端都是出於安全原因做這些事情。 – DBADon