在 Oracle 中使用内部连接(inner join)来进行更新操作失败

我有一个查询,在MySQL工作得很好,但当我在Oracle上运行它时,我得到以下错误:

SQL Error: ORA-00933: SQL command not incorrect ended
. SQL Error: ORA-00933: SQL command not incorrect ended 00933. 00000 - "SQL命令未正确结束"

. 00000 - "SQL命令未正确结束

查询为:

UPDATE table1
INNER JOIN table2 ON table1.value = table2.DESC
SET table1.value = table2.CODE
WHERE table1.UPDATETYPE='blah';
963828 次浏览

该语法在Oracle中无效。你可以这样做:

UPDATE table1 SET table1.value = (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC)
WHERE table1.UPDATETYPE='blah'
AND EXISTS (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC);

或者你可能可以这样做:

UPDATE
(SELECT table1.value as OLD, table2.CODE as NEW
FROM table1
INNER JOIN table2
ON table1.value = table2.DESC
WHERE table1.UPDATETYPE='blah'
) t
SET t.OLD = t.NEW
这取决于Oracle是否认为内联视图可更新 第二个语句是否可更新取决于列出的一些规则 在这里 < / em >)。< / p >
 UPDATE ( SELECT t1.value, t2.CODE
FROM table1 t1
INNER JOIN table2 t2 ON t1.Value = t2.DESC
WHERE t1.UPDATETYPE='blah')
SET t1.Value= t2.CODE

用这个:

MERGE
INTO    table1 trg
USING   (
SELECT  t1.rowid AS rid, t2.code
FROM    table1 t1
JOIN    table2 t2
ON      table1.value = table2.DESC
WHERE   table1.UPDATETYPE='blah'
) src
ON      (trg.rowid = src.rid)
WHEN MATCHED THEN UPDATE
SET trg.value = code;

对table2使用描述而不是desc,

update
table1
set
value = (select code from table2 where description = table1.value)
where
exists (select 1 from table2 where description = table1.value)
and
table1.updatetype = 'blah'
;

下面的语法适合我。

UPDATE
(SELECT A.utl_id,
b.utl1_id
FROM trb_pi_joint A
JOIN trb_tpr B
ON A.tp_id=B.tp_id Where A.pij_type=2 and a.utl_id is null
)
SET utl_id=utl1_id;
UPDATE table1 t1
SET t1.value =
(select t2.CODE from table2 t2
where t1.value = t2.DESC)
WHERE t1.UPDATETYPE='blah';

带有WHERE子句的MERGE:

MERGE into table1
USING table2
ON (table1.id = table2.id)
WHEN MATCHED THEN UPDATE SET table1.startdate = table2.start_date
WHERE table1.startdate > table2.start_date;

你需要WHERE子句,因为在ON子句中引用的列不能被更新。

它工作得很好

merge into table1 t1
using (select * from table2) t2
on (t1.empid = t2.empid)
when matched then update set t1.salary = t2.salary
update table1  a
set a.col1='Y'
where exists(select 1
from table2 b
where a.col1=b.col1
and a.col2=b.col2
)
UPDATE IP_ADMISSION_REQUEST ip1
SET IP1.WRIST_BAND_PRINT_STATUS=0
WHERE IP1.IP_ADM_REQ_ID        =
(SELECT IP.IP_ADM_REQ_ID
FROM IP_ADMISSION_REQUEST ip
INNER JOIN VISIT v
ON ip.ip_visit_id=v.visit_id
AND v.pat_id     =3702
); `enter code here`

正如在这里所指出的,Tony Andrews提出的第一个解决方案的通用语法是:

update some_table s
set   (s.col1, s.col2) = (select x.col1, x.col2
from   other_table x
where  x.key_value = s.key_value
)
where exists             (select 1
from   other_table x
where  x.key_value = s.key_value
)

我认为这很有趣,特别是当你想要更新多个字段时。

不要使用上面的一些答案。

有些人建议使用嵌套SELECT,不要这样做,它非常慢。如果你有很多记录要更新,使用join,就像这样:

update (select bonus
from employee_bonus b
inner join employees e on b.employee_id = e.employee_id
where e.bonus_eligible = 'N') t
set t.bonus = 0;

参见此链接了解更多细节。 http://geekswithblogs.net/WillSmith/archive/2008/06/18/oracle-update-with-join-again.aspx . < / p >

另外,确保所有要连接的表上都有主键。

UPDATE (SELECT T.FIELD A, S.FIELD B
FROM TABLE_T T INNER JOIN TABLE_S S
ON T.ID = S.ID)
SET B = A;

A和B是别名字段,不需要指向表。

只是作为一个完整的问题,因为我们谈论的是Oracle,这也可以做到:

declare
begin
for sel in (
select table2.code, table2.desc
from table1
join table2 on table1.value = table2.desc
where table1.updatetype = 'blah'
) loop
update table1
set table1.value = sel.code
where table1.updatetype = 'blah' and table1.value = sel.desc;
end loop;
end;
/

甲骨文基地在这方面做得很好。

https://oracle-base.com/articles/misc/updates-based-on-queries

从这个链接-我使用了上述查询的修改,这对我来说没有作用(答案来自mathguy,它使用rowid)

MERGE /*+ APPEND PARALLEL(8) */ INTO dest_table tt
USING source_table st
ON (tt.identifier = st.identifier)
WHEN MATCHED THEN
UPDATE SET tt.number = st.number;

这里我有两个表:source和dest,它们都有一个共同的varchar字段,我将源标识字段(PK)添加到dest表中。