Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用INSERT…SELECT返回的替代方法_Sql_Oracle_Sql Insert_Insert Select_Sql Returning - Fatal编程技术网

Sql 使用INSERT…SELECT返回的替代方法

Sql 使用INSERT…SELECT返回的替代方法,sql,oracle,sql-insert,insert-select,sql-returning,Sql,Oracle,Sql Insert,Insert Select,Sql Returning,有这样一种情况,即通过复制另一个表中的某些列并从该插入中返回生成的键来插入到一个表中。使用Oracle数据库 这基本上是出于本能,导致编写这个查询 INSERT INTO TBL_XXX SELECT COLA, COLB, COLC FROM TBL_YYY RETURNING COLA INTO COL_RES 由于某些正当理由,这是不允许的 是否有替代方法?您正在使用插入到。。。从construct中选择。因此,语句可能会插入多行,这意味着RETURNING子句将返回多行。因此,您需要使

有这样一种情况,即通过复制另一个表中的某些列并从该插入中返回生成的键来插入到一个表中。使用Oracle数据库

这基本上是出于本能,导致编写这个查询

INSERT INTO TBL_XXX
SELECT COLA, COLB, COLC FROM TBL_YYY
RETURNING COLA INTO COL_RES
由于某些正当理由,这是不允许的


是否有替代方法?

您正在使用插入到。。。从construct中选择。因此,语句可能会插入多行,这意味着RETURNING子句将返回多行。因此,您需要使用批量收集语法来填充新键的集合

所以我们试着这样做

declare
    /* NB: define this collection using the appropriate name  */
    type new_keys is table of table_xxx.cola%type;
    col_res new_keys;
begin
    INSERT INTO TBL_XXX
    SELECT COLA * 10, COLB, COLC FROM TBL_YYY
    RETURNING table_xxx.COLA bulk collect INTO COL_RES;
end;
/
。。。只为了得到:

ORA-06550:第8行第15列:
PL/SQL:ORA-00933:SQL命令未正确结束

那太糟糕了

不幸的是,在将批量收集返回到具有更新和删除功能的情况下,它不适用于插入(或合并)。我确信在Oracle内核的内部架构中有很好的理由,但这应该是可行的,而且这不是最烦人的

无论如何,正如@Poundstibbons指出的,有一个解决方法:FORALL构造

declare
    type new_rows is table of tbl_xxx%rowtype;
    rec_xxx new_rows;
    type new_keys is table of tbl_xxx.cola%type;
    col_xxx new_keys;
begin
    select cola * 10, colb, colc 
    bulk collect into rec_xxx
    from tbl_yyy;

    forall idx in 1 .. rec_xxx.count()
        insert into tbl_xxx
        values rec_xxx(idx)
        returning tbl_xxx.cola bulk collect into col_xxx
    ;

    for idx in 1 .. rec_xxx.count() loop
        dbms_output.put_line('tbl_xxx.cola = ' || col_xxx(idx));
   end loop;
end;
/

这是

第二个insert查询,可能编写为触发器。在您的查询中,它看起来不像是返回生成的密钥
COLA
,因为它是
select
的一部分。您是否使用序列或任何其他表达式表示
COLA
?或者是别的什么?col_res是作为标量变量声明的,还是作为数组声明的?我怀疑是前者。或者COLA是TBL_YYY列的名称,但是TBL_XXX的第一列名称不同。(顺便说一句,您应该始终明确声明要插入的列的名称,以避免表之间的列顺序不同等问题)@KaushikNayak我期待着阅读TBL_XXX生成的键。可能会更新问题。恐怕
insert。。。选择…
与返回的
不起作用,至少我得到了ORA-00933,我们需要这里。@Pounderstibbons-我重写了我的答案,以演示如何使用FORALL实现解决方案^1,向我们展示如何熟练地处理答案:-)