无法单独更新行

问题描述:

我试图更新我们的系统中的患者表,但由于我们与将状态发送到外部系统的状态发生连接,因此无法进行大规模更新我们的系统中有几个触发器(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

开发人员认为这不是一个好主意。无论如何,我不明白这里的全部故事 –

拥有了完整的代码,这是很难。我猜你的更新语句下面的代码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'触发器会削弱基本的数据库功能(批量数据更改),您真的需要考虑它为什么存在以及如何永久删除它。这是一个坏主意,它闻起来像有人不明白触发器 –

如果你添加到你的更新代码中的“GO 100”,那应该可以做到。如果触发器的更新速度过快,您可能还需要延迟。

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

执行次数(在我的例子中为100)取决于你。

+0

我们对一些客户端服务器有类似的限制,我们只能一次更新一些安全设置。进行这些更改需要更长的时间,但无论是好还是坏,客户端都是出于安全原因做这些事情。 – DBADon