0

我正在尝试在 ORACLE 中使用 SELECT 语句编写 UPDATE 语句,但我一直收到“无效标识符”错误。我确信该领域存在。

这是我的 SQL:

update 
(
select distinct a.item_id, a.account_code, b.item_id, b.account_code
from bp.poline a, mt.material b 
where a.item_id = b.item_id  
and a.account_code is not null and b.account_code is null
)
set b.account_code = a.account_code

这是我得到的错误:

Error report:
SQL Error: ORA-00904: "A"."ACCOUNT_CODE": invalid identifier
00904. 00000 -  "%s: invalid identifier
4

2 回答 2

4

在 Oracle 中,只有当 Oracle 能够为子查询的每一行准确定位基表中的一行且仅一行时,您才能更新子查询。此外,对分析功能、聚合等的使用还有其他限制。

在您的示例中,这DISTINCT将使 Oracle 无法更新子查询,因为子查询的一行可能指向基表的行。

如果删除DISTINCT,则查询仅在存在唯一索引时才有效MATERIAL(item_id),因此表中的每一行POLINE最多只能与 中的一行相关联MATERIAL

UPDATE (SELECT a.item_id, a.account_code acct_a, 
               b.item_id, b.account_code acct_b
          FROM bp.poline a, mt.material b
         WHERE a.item_id = b.item_id
           AND a.account_code IS NOT NULL
           AND b.account_code IS NULL)
   SET acct_a = acct_b

更新一个连接是非常有效的,但是有几个限制,如果你没有这个索引怎么办?

您可以使用不同的子查询编写标准更新:

UPDATE poline a
   SET a.account_code = (SELECT b.account_code
                           FROM material b
                          WHERE b.item_id = a.item_id
                            AND b.account_code is not null)
 WHERE a.account_code IS NULL
   AND a.item_id IN (SELECT b.item_id 
                       FROM material b
                      WHERE b.account_code IS NOT NULL)

然而,受类似问题的回答启发,IMO 最优雅的解决方案是:

MERGE INTO (SELECT * FROM a WHERE account_code IS NULL) a
     USING (SELECT * FROM b WHERE account_code IS NOT NULL) b
        ON (a.item_id = b.item_id)
WHEN MATCHED THEN UPDATE SET a.account_code = b.account_code;
于 2013-02-20T09:50:36.933 回答
0

在下面的SQL中使用update语句和select语句是语法......它在我的代码中工作,我正在使用派生表可能是这个 vl 帮助你

例如……

更新SHIFT_MST SET SHIFT_MST.SHIFT_DESC=A.SHIFT_DESC,SHIFT_MST.SHIFT_CODE=A.SHIFT_CODE

( SELECT * FROM TEMP_SHIFT_MST)a

其中 a.SHIFT_ID=SHIFT_MST.SHIFT_ID

于 2013-02-20T09:46:35.770 回答