我使用merge
语句插入新数据或删除数据。我使用temp table
作为source
,将表格作为target
。
目标表的foreign ke
y与另一个表(Table A
)。
有时执行(when matched then delete
语句)时会遇到以下错误。
error:
Attempting to set a non-NULL-able column's value to NULL.
如果我评论此行,则查询运行完美。
同样如果我删除了foreign key
和Material table
之间的table A
,那么查询也会完美运行。
我已应用此Hotfix但我已提到问题。
SQL Server版本:Microsoft SQL Server 2008 R2 (SP1) - 10.50.2550.0 (X64)
**Target Tbale (Material)** **Table A**
PatientIdRef (ForeignKey) PatientId(Primary Key)
VisitNumberRef(Foreign Key) VisitNumber(Primary Key)
Unit_Price Name
Unit_Price_Ins family
....
....
create tabl #Temp
(
patinetId [varchar](50) NOT NULL,
[Visit_Number] [smallint] NULL,
[Unit_Price] [float] NULL,
[Unit_Price_Ins] [float] NULL,
......
.....
)
merge materials as target
using(select patinetId ,Visit_Number,Unit_Price,Unit_Price_Ins
from #Temp
) as source
on (source.patientid=target.patientid collate arabic_ci_as and source.visit_number=target.visit_number)
when matched then delete
when not matched then insert
(patinetIdref ,Visit_Numberref,Unit_Price,Unit_Price_Ins )
values(patinetId ,Visit_Number,Unit_Price,Unit_Price_Ins)
答案 0 :(得分:1)
由于在目标表具有多个外键(FK)约束的情况下遇到此问题,因此很可能是由于此错误:FIX: "Attempting to set a non-NULL-able column's value to NULL" error message when you use a MERGE statement in SQL Server 2008, in SQL Server 2008 R2 or in SQL Server 2012
您正在运行SQL Server 2008 R2 SP1版本10.50.2550
SQL Server 2008 R2 SP1版本10.50.2822及更高版本(累积更新8)中已修复此问题。
从这里下载:Cumulative update package 8 for SQL Server 2008 R2 Service Pack 1
或者最好下载适用于SQL Server 2008 R2 SP1的最新累积更新:Cumulative update package 13 for SQL Server 2008 R2 SP1
您提到您已经为此应用了一个SQL Server修补程序,但我建议您通过执行SELECT @@VERSION
并验证版本号是否为10.50.2822或更高版本来仔细检查它是否已正确安装。
答案 1 :(得分:0)
基于以下内容:
MERGE
语句在没有when matched then delete
或没有外键约束的情况下工作我怀疑问题是外键约束指向配置为Materials
的{{1}}表。您可以使用ON DELETE SET NULL
Materials
答案 2 :(得分:0)
通过将select移出using语句并将其放入临时表中,我能够“修复”此错误。
就是说,我改变了这个:
MERGE dbo.IVS_LIVE t
USING (SELECT PolicyNumber
,EffectiveDate
,cast(null as date) as TerminationDate
,CAST('CRS' as CHAR(4)) as datasource
,VIN
,State
,IVS_RUNHISTORY_ID
FROM dbo.IVS_CRS_STAGING
WHERE PolicyStatus in (10, 60, 70)
OR ( PolicyStatus not in (10, 60, 70, 99)
AND PolicyStatusDate >= (select irh.RunDate
from dbo.IVS_RUNHISTORY irh
where irh.ID = @ivs_runhistory_id
)
)
) as s
对此:
MERGE dbo.IVS_LIVE t
USING #sourcetbl as s
我想更简单的代码不会在我被迫使用的非常老版本的sql server中触发该错误: