0

我正在尝试使用合并,我可以看到以下错误

ORA-00928: 缺少 SELECT 关键字

  merge into table using(select * from table on val = val1)
  when matched then
  (update set
     val2 = val3 where val = val1)
  when not matched then
  (Insert query)

我错过了什么?

4

2 回答 2

1

语法非常规范。匹配条件属于单独的 ON 子句,并且必须放在括号中。 了解更多

SQL> merge into t23 tgt
  2  using ( select * from t23 ) q
  3  on (tgt.col1 = q.col1)
  4  when not matched then
  5      insert values (q.col1, q.id+20, q.col2, q.date_time, q.qty, q.dt)
  6  when matched then
  7      update set tgt.col2 = q.col2 * 2
  8  /

4 rows merged.

SQL> 

“我到处都在使用同一张桌子,这可能是问题吗?”

没有。正如我的示例查询所示,MERGE 可以使用与源和目标相同的表运行。但是,问题是您为什么要这样做?要么所有的行都匹配,在这种情况下你正在做一个update,或者没有匹配,这是一个insert ... select from.


再次查看您的伪查询后,我想我可以看到您正在尝试做什么。诀窍是确保 ON 子句中的条件匹配目标集中的一行与 USING 集中的一行。不然会摔ORA-30926: unable to get a stable set of rows in the source tables

所以这是我之前查询的重新处理版本。

起始数据集(USING 集):

SQL> select id, col1, qty, col2 from t23;

ID                                   COL1        QTY C
------------------------------ ---------- ---------- -
ABCD0001                                5        100 N
ABCD0002                               10         10 N
ABCD0003                               15         20 N
ABCD0004                               20        -30 N
ABCD0005                               35         20 N
ABCD0006                               25        100 N
ABCD0007                               30         30 N
ABCD0008                               40        -30 N

8 rows selected.

SQL>

ON 条件连接两列以保证稳定的集合:

SQL> merge into t23 tgt
  2  using ( select * from t23 ) q
  3  on (tgt.id = q.id 
  4       and tgt.col1 = tgt.qty)
  5  when not matched then
  6      insert values (q.id, q.col1+20, 'X', q.date_time, q.qty, q.dt)
  7  when matched then
  8      update set tgt.col2 = 'Y'
  9  /

8 rows merged.

SQL>

结果是两次更新和六次插入......

SQL> select id, col1, qty, col2 from t23;

ID                                   COL1        QTY C
------------------------------ ---------- ---------- -
ABCD0001                                5        100 N
ABCD0002                               10         10 Y
ABCD0003                               15         20 N
ABCD0004                               20        -30 N
ABCD0005                               35         20 N
ABCD0006                               25        100 N
ABCD0007                               30         30 Y
ABCD0008                               40        -30 N
ABCD0008                               60        -30 X
ABCD0004                               40        -30 X
ABCD0001                               25        100 X
ABCD0003                               35         20 X
ABCD0006                               45        100 X
ABCD0005                               55         20 X

14 rows selected.

SQL> 

这种策略的明显危险是主键冲突。我的桌子是小事,没有主键。在现实生活中,您的表应该有一个主键,您需要在 INSERT 子句中处理它。


有趣的是,UPDATE 分支中的 WHERE 子句是合法的语法(尽管它在 OP 的示例中是多余的,因为它重复了 ON 标准)。针对原始数据集运行此 MERGE 合并六行(六次插入,无更新):

merge into t23 tgt
using ( select * from t23 ) q
on (tgt.id = q.id 
     and tgt.col1 = tgt.qty)
when not matched then
    insert values (q.id, q.col1+20, 'X', q.date_time, q.qty, q.dt)
when matched then
    update set tgt.col2 = 'Y'
    where tgt.col2 = 'Z'
/

WHERE 子句仅适用于 MATCHED 分支,用于确定匹配的行是更新还是删除。

于 2015-06-04T03:46:53.660 回答
0

连接条件错误:

merge into table using (
   select * from table 
) on val = val1 --<< needs to go outside of the sub-select 
when matched then
(update set
   val2 = val3 where val = val1)
when not matched then
(Insert query)
于 2015-06-03T22:16:37.590 回答