具有相关子查询的更新查询不能通过表别名
Posted
技术标签:
【中文标题】具有相关子查询的更新查询不能通过表别名【英文标题】:Update query with correlated subquery can't go through table alias 【发布时间】:2020-09-23 08:58:09 【问题描述】:我的 SQL Server 上有这个更新查询
UPDATE BK_TT_DELIVERY_PLAN TDP
SET (PACK_TYPE) =
(SELECT OPD.PACKING_TYPE
FROM TT_OM_PACK_DISCREPANCY OPD
WHERE ISNULL(TDP.PO_REF,TDP.PO_NUMBER) = OPD.PO_NUMBER
AND TDP.PO_ITEM = ODP.PO_ITEM)
WHERE
EXISTS (SELECT 1
FROM TT_OM_PACK_DISCREPANCY OPD
WHERE ISNULL(TDP.PO_REF,TDP.PO_NUMBER) = OPD.PO_NUMBER
AND TDP.PO_ITEM = ODP.PO_ITEM)
当我尝试执行时,我总是收到此错误:
查找错误 - SQL Server 数据库错误:“TDP”附近的语法不正确
我在 Oracle 上试了一下,效果很好。
此问题的任何解决方法?
谢谢。
【问题讨论】:
【参考方案1】:您不在UPDATE
子句中为表设置别名,而是在FROM
中这样做。由于此语句中没有FROM
,因此您不要为表指定别名。但是,这意味着您必须将查询中的所有别名更改为表的名称:
UPDATE dbo.BK_TT_DELIVERY_PLAN
SET (PACK_TYPE) =
(SELECT OPD.PACKING_TYPE
FROM TT_OM_PACK_DISCREPANCY OPD
WHERE ISNULL(BK_TT_DELIVERY_PLAN.PO_REF,BK_TT_DELIVERY_PLAN.PO_NUMBER) = OPD.PO_NUMBER
AND BK_TT_DELIVERY_PLAN.PO_ITEM = ODP.PO_ITEM)
WHERE EXISTS
(SELECT 1
FROM TT_OM_PACK_DISCREPANCY OPD
WHERE ISNULL(BK_TT_DELIVERY_PLAN.PO_REF,BK_TT_DELIVERY_PLAN.PO_NUMBER) = OPD.PO_NUMBER
AND BK_TT_DELIVERY_PLAN.PO_ITEM = ODP.PO_ITEM);
因此使用FROM
可能是一个更好的主意,然后在UPDATE
子句中引用别名:
UPDATE TDP
SET (PACK_TYPE) =
(SELECT OPD.PACKING_TYPE
FROM TT_OM_PACK_DISCREPANCY OPD
WHERE ISNULL(TDP.PO_REF,TDP.PO_NUMBER) = OPD.PO_NUMBER
AND TDP.PO_ITEM = ODP.PO_ITEM)
FROM dbo.BK_TT_DELIVERY_PLAN TDP
WHERE EXISTS
(SELECT 1
FROM TT_OM_PACK_DISCREPANCY OPD
WHERE ISNULL(TDP.PO_REF,TDP.PO_NUMBER) = OPD.PO_NUMBER
AND TDP.PO_ITEM = OPD.PO_ITEM);
另外注意,您不应该使用ISNULL
是WHERE
(或ON
),因为它会导致查询变得不可搜索。使用正确的布尔逻辑。同样,使用 JOIN
而不是 2 个子查询,这似乎也可以变得更小。
UPDATE TDP
SET PACK_TYPE = OPD.PACKING_TYPE
FROM dbo.BK_TT_DELIVERY_PLAN TDP
JOIN TT_OM_PACK_DISCREPANCY OPD ON (TDP.PO_REF = OPD.PO_NUMBER
OR (TDP.PO_REF IS NULL AND TDP.PO_NUMBER = OPD.PO_NUMBER))
AND TDP.PO_ITEM = OPD.PO_ITEM;
【讨论】:
使用第二个查询返回:无法绑定多部分标识符“ODP.PO_ITEM”。 正如 Gordon 刚刚通过他们的编辑 @Syns 演示的那样,这确实是您原始代码中的一个印刷错误。你有AND TDP.PO_ITEM = ODP.PO_ITEM
,但将对象TT_OM_PACK_DISCREPANCY
别名为OPD
,而不是ODP
;因此错误。
@lamu 哦该死,我没有注意到印刷错误。我的错。感谢指正
@gordon-linoff 谢谢,这是我的新见解,我将使用第三个查询,【参考方案2】:
简单查询,请按照以下查询。在哪里使用联合查询结果和更新记录。
UPDATE TDP
SET TDP.PACK_TYPE = OPD.PACKING_TYPE
FROM dbo.BK_TT_DELIVERY_PLAN TDP
LEFT OUTER JOIN TT_OM_PACK_DISCREPANCY OPD ON ISNULL(TDP.PO_REF,TDP.PO_NUMBER) = OPD.PO_NUMBER AND TDP.PO_ITEM = ODP.PO_ITEM
WHERE OPD.PACKING_TYPE IS NOT null
【讨论】:
以上是关于具有相关子查询的更新查询不能通过表别名的主要内容,如果未能解决你的问题,请参考以下文章