Oracle 上使用内连接更新语句

发布于 2024-08-25 08:01:00 字数 319 浏览 12 评论 0原文

我有一个在 MySQL 中运行良好的查询,但是当我在 Oracle 上运行它时,出现以下错误:

SQL 错误:ORA-00933:SQL 命令未正确结束
00933. 00000 - “SQL 命令未正确结束”

查询是:

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

I have a query which works fine in MySQL, but when I run it on Oracle I get the following error:

SQL Error: ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"

The query is:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

清君侧 2024-09-01 08:01:01

该语法在 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 是否认为内联视图可更新
第二条语句的可更新取决于列出的一些规则
此处
)。

That syntax isn't valid in Oracle. You can do this:

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);

Or you might be able to do this:

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

It depends if the inline view is considered updateable by Oracle
( To be updatable for the second statement depends on some rules listed
here
).

笑叹一世浮沉 2024-09-01 08:01:01

使用这个:

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;

Use this:

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;
橘虞初梦 2024-09-01 08:01:01

带有 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 with WHERE clause:

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;

You need the WHERE clause because columns referenced in the ON clause cannot be updated.

沙与沫 2024-09-01 08:01:01

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

有些人建议使用嵌套 SELECT,不要这样做,它非常慢。如果您有大量记录需要更新,请使用联接,例如:

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

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

Do not use some of the answers above.

Some suggest the use of nested SELECT, don't do that, it is excruciatingly slow. If you have lots of records to update, use join, so something like:

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;

See this link for more details.
http://geekswithblogs.net/WillSmith/archive/2008/06/18/oracle-update-with-join-again.aspx.

Also, ensure that there are primary keys on all the tables you are joining.

偏闹i 2024-09-01 08:01:01
 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
 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
清音悠歌 2024-09-01 08:01:01

此处所示,第一个解决方案的一般语法由托尼·安德鲁斯:

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
                         )

我认为这很有趣,特别是如果您想要更新多个字段。

As indicated here, the general syntax for the first solution proposed by Tony Andrews is :

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
                         )

I think this is interesting especially if you want update more than one field.

无力看清 2024-09-01 08:01:01

甲骨文运行良好

merge into table1 t1
using (select * from table2) t2
on (t1.empid = t2.empid)
when matched then update set t1.salary = t2.salary

It works fine oracle

merge into table1 t1
using (select * from table2) t2
on (t1.empid = t2.empid)
when matched then update set t1.salary = t2.salary
贪了杯 2024-09-01 08:01:01

以下语法对我有用。

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;

This following syntax works for me.

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;
路还长,别太狂 2024-09-01 08:01:01

使用 description 代替 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'
;

Using description instead of desc for table2,

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'
;
假情假意假温柔 2024-09-01 08:01:01
UPDATE table1 t1
SET t1.value = 
    (select t2.CODE from table2 t2 
     where t1.value = t2.DESC) 
WHERE t1.UPDATETYPE='blah';
UPDATE table1 t1
SET t1.value = 
    (select t2.CODE from table2 t2 
     where t1.value = t2.DESC) 
WHERE t1.UPDATETYPE='blah';
流星番茄 2024-09-01 08:01:01
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是别名字段,不需要指向表。

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 and B are alias fields, you do not need to point the table.

夜清冷一曲。 2024-09-01 08:01:01

出于完整性考虑,并且因为我们谈论的是 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;
/

Just as a matter of completeness, and because we're talking Oracle, this could do it as well:

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;
/
蔚蓝源自深海 2024-09-01 08:01:01
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`
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`
樱桃奶球 2024-09-01 08:01:01

甲骨文基地在这方面有很好的表现。

https://oracle-base.com/articles/misc/updates-基于查询

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

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;

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

Oracle base has a good run down on this.

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

From this link - I used a modification of the above query which did not work for me (the answer from mathguy which uses 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;

Here I have two tables: source and dest. They both have a varchar field in common and I am adding the source identify field (PK) into the dest table.

离去的眼神 2024-09-01 08:01:01

Oracle Database 23ai 添加了对 updatedelete 中直接联接的支持:

select employee_id, salary from hr.employees 
where  job_id = 'ST_MAN';

EMPLOYEE_ID     SALARY
----------- ----------
        120       8000
        121       8200
        122       7900
        123       6500
        124       5800

update hr.employees e
set    salary = max_salary 
from   hr.jobs j
where  j.job_id = e.job_id;

select employee_id, salary from hr.employees 
where  job_id = 'ST_MAN';

EMPLOYEE_ID     SALARY
----------- ----------
        120       8500
        121       8500
        122       8500
        123       8500
        124       8500

Oracle Database 23ai has added support for direct joins in update and delete:

select employee_id, salary from hr.employees 
where  job_id = 'ST_MAN';

EMPLOYEE_ID     SALARY
----------- ----------
        120       8000
        121       8200
        122       7900
        123       6500
        124       5800

update hr.employees e
set    salary = max_salary 
from   hr.jobs j
where  j.job_id = e.job_id;

select employee_id, salary from hr.employees 
where  job_id = 'ST_MAN';

EMPLOYEE_ID     SALARY
----------- ----------
        120       8500
        121       8500
        122       8500
        123       8500
        124       8500
逆夏时光 2024-09-01 08:01:01
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 table1  a 
   set a.col1='Y' 
 where exists(select 1 
                from table2 b
               where a.col1=b.col1 
                 and a.col2=b.col2
             )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文