使用SELECT的UPDATE语句

时间:2013-02-20 09:39:49

标签: sql oracle

我正在尝试在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

2 个答案:

答案 0 :(得分:4)

在Oracle中,只有当Oracle能够为子查询的每一行精确定位一行且只有一行基本表时,才能更新子查询。此外,additional restrictions apply涉及分析功能,聚合等的使用

在您的示例中,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)

然而,受answer to a similar question启发的最优雅的解决方案是:

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;

答案 1 :(得分:0)

使用更新语句与选择语句在 SQL 下面是语法...并且它在我的代码中工作 在这我使用派生表 可能是这个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