使用多个选择和减号运算符的PL / SQL插入

时间:2016-08-19 15:04:51

标签: oracle plsql oracle-apex

以下作品:

INSERT INTO BASE_TABLE
(
    req, 
    desc,
    ver
)
    SELECT * FROM UPDATE_TABLE
minus
    SELECT req, desc, ver FROM BASE_TABLE;

但是,这会导致错误(只是尝试插入一个字段:' key'):

INSERT INTO BASE_TABLE
(
    req, 
    desc,
    ver,
    key        
)
    SELECT * FROM UPDATE_TABLE
minus
    SELECT req, desc, ver FROM BASE_TABLE,
    SELECT CONCAT(req, ver) FROM UPDATE_TABLE;

错误:

PL / SQL:ORA-00903:表名无效

尝试通过从UPDATE表中选择BASE_TABLE中尚未存在的所有内容,将行插入BASE_TABLE。只是想添加'键'字段。

最后一个SELECT似乎不合适并导致此错误。 是' SELECT ...减去SELECT ...'等于一个语句,所以第三个SELECT语句需要分开吗?但是如何?

3 个答案:

答案 0 :(得分:2)

要使它工作as_is,你的最后一个" SELECT"实际上应该转到外部查询,如下所示:

INSERT INTO BASE_TABLE
(
    req, 
    desc,
    ver,
    key        
)
    SELECT req, desc, ver, CONCAT(req, ver)
    FROM 
    ( SELECT * FROM UPDATE_TABLE
      minus
      SELECT req, desc, ver FROM BASE_TABLE
    );

注意:这是一个懒惰的"解决方案,应该没有SELECT *,列名应该全部拼写出来。我只是跟着你的主角......现在,UPDATE_TABLE应该有正确数量的列,正确的名称和正确的顺序,因为你说你的第一个查询有效(它不会工作除此以外)。但是,如果将来向UPDATE_TABLE添加一列,则SELECT *的查询将不再有效,但具有完整列名称的查询将不会受到影响。

答案 1 :(得分:0)

基于mus shou的两个select包含相同数量和类型的列

尝试使用

SELECT req, desc, ver FROM UPDATE_TABLE
 minus
SELECT req, desc, ver FROM BASE_TABLE

答案 2 :(得分:0)

MERGE解决方案:插图

文档https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm

我创建了两个小桌子用于说明。请参阅我对原始帖子的评论:desckey是保留字,因此它们不能用作列名,我相应地更改了它们。我使用||运算符进行串联和显式转换为字符数据类型(VARCHAR2)。

创建小型测试表:

create table  base_table ( req, dscr, ver, ky ) as 
       select 1, 'alpha', 235, '1235' from dual union all
       select 2, 'beta' , 33 , '233'  from dual
;
select * from base_table;

       REQ DSCR         VER KY 
---------- ----- ---------- ----
         1 alpha        235 1235
         2 beta          33 233

create table update_table (req, dscr, ver) as
   select 1, 'alpha', 235 from dual union all
   select 5, 'rho'  , 444 from dual
;
select * from update_table;

       REQ DSCR         VER
---------- ----- ----------
         1 alpha        235
         5 rho          444

MERGE解决方案和结果:

merge into base_table   b
    using  update_table u
    on     (b.req = u.req and b.dscr = u.dscr and b.ver = u.ver)
  when not matched then
    insert (   req,   dscr,   ver, ky                               )
    values ( u.req, u.dscr, u.ver, to_char(u.req) || to_char(u.ver) )
;

select * from base_table;

       REQ DSCR         VER KY 
---------- ----- ---------- ----
         1 alpha        235 1235
         2 beta          33 233 
         5 rho          444 5444