我正在运行带有多个CTE的大型更新查询,以更新表" a"中的许多列(50 ),其中来自表" b"中的列中的值。当查询完成时,表A中的所有列都已成功更新,除了两个包含大量空值的列(我想说75%的空值)。这是完全出乎意料的,因为表A或表B中的两个列都不包含任何null值。
简化的示例代码(仅显示有问题的两个列的最终CTE ):
WITH B AS
(SELECT T.position
,CASE WHEN CTE1.full_name = '' THEN CTE2._name
ELSE CTE1.full_name
END AS Name
,CASE WHEN CTE1.emp_id = '' THEN CTE2.emp_id
ELSE CTE1.emp_id
END AS Id
FROM T
LEFT JOIN CTE1
ON T.code = CTE1.code
LEFT JOIN CTE2
ON T.code = CTE2.code
)
UPDATE A
SET A.Name = B.Name, A.Id = B.Id
FROM A
LEFT JOIN B
ON A.code = B.code
这个问题是黑暗中的镜头,因为我知道这个简化的代码可能太笼统了,无法得出任何结论。如果有人在上述情况下确实有任何事先具有意外零值的经验,那么任何麻烦的射击技巧都将不胜感激,因为我不确定从哪里开始寻找。
进行故障排除(并永久停止使用更新...从)添加另一个CTE,例如:
WITH B AS
(SELECT T.position
,CASE WHEN CTE1.full_name = '' THEN CTE2._name
ELSE CTE1.full_name
END AS Name
,CASE WHEN CTE1.emp_id = '' THEN CTE2.emp_id
ELSE CTE1.emp_id
END AS Id
FROM T
LEFT JOIN CTE1
ON T.code = CTE1.code
LEFT JOIN CTE2
ON T.code = CTE2.code
), C as
(
select a.Name a_name, b.Name b_name, a.ID a_id, b.ID b_id
FROM A
LEFT JOIN B
ON A.code = B.code
)
select * from c
--update C set a_name = b_name, a_id = b_id
检查结果,故障排除,然后切换到更新。
您正在做一个从A到B的左联接。这意味着如果没有匹配的b行,则a桌一行,那么b中的所有值都将为null。这几乎可以肯定是您的零值来自的位置。
您可以进行内部加入,以便您只能在表A中更新具有匹配b行的行。这将阻止您获得无效的值,但可能不是您需要的 - 某些桌子根本不会更新。
如果您需要在没有B行的情况下将一些默认值放入A中,则您仍然需要进行左键,但是将设置命令更改为
之类的东西SET A.Name = COALESCE(B.Name, "defaultvalue")
如果您认为每行都应该有一个匹配行,则需要调试您的CTE,并找出哪个没有返回您期望的值。