合并SQL语句和匹配记录转换

时间:2013-05-30 19:18:57

标签: sql sql-server merge

我在SQL Server中的查询看起来只尝试合并已更改的记录而不是更新每一个记录,因此我在MATCHED子句之后插入一个简单的AND语句,除了一件事之外它完美地工作。在C#中,我理解你如何将变量转换为不同的类型以便比较它们,但我在SQL中“假设”并非如此。源列是数字(19,5),目标是十进制(18,4)。出于我们的目的,我并不担心截断数据,最终我会改变目标,因此它将保持更多,即(20,6)

以下是声明:

WHEN MATCHED 
AND (((ISNULL(source.WorkOrderItemNumber,'') != ISNULL(target.WorkOrderItemNumber,'')) 
OR (ISNULL(CAST(source.WorkOrderQty as DECIMAL(18,4)),0) != ISNULL(target.WorkOrderQty,0)

-- ISNULL(source.WorkOrderQty,0) != ISNULL(target.WorkOrderQty,0)

) 

OR (ISNULL(source.WorkOrderBatchQty,0) != ISNULL(target.WorkOrderBatchQty,0)

))) 

当我运行上面的语句时,它会执行正确的操作,并且不会运行相应的更新语句。当我取消注释第二行并使用它时,它无法正常工作。它会说记录不同并运行相应的UPDATE语句。

WorkOrderBatchQty正常工作,但不同之处在于我将0.00000 AS WorkOrderBatchQty硬编码到语句中,目标目标是十进制(18,4)

我可以看到它为什么会起作用,但我不明白为什么它不能兼顾两种方式?我不认为SQL在比较值时会使用这种方式。我猜14.00000与14.0000不同,但我不认为SQL会关心。

由于

1 个答案:

答案 0 :(得分:1)

根据MSDN类型转换图表,十进制和数字转换(r)equires explicit CAST to prevent the loss of precision or scale that might occur in an implicit conversion。寻找图表中的大星号。

所以你需要一个内联类型转换,如:

ISNULL(CAST(source.WorkOrderQty AS DECIMAL(18, 4)), 0) != ISNULL(target.WorkOrderQty, 0)