编写一个带有select子句的insert语句,在oracle中返回id

时间:2018-03-07 05:05:14

标签: sql oracle plsql

我正在尝试编写如下查询:

例如:

 DECLARE 
 V_Output varchar(20):='';

 BEGIN
   INSERT INTO T(ID, MY_PK, NAME, VALUE)
   (SELECT ID, NEXT_TRAN_VALUE('T'), NAME, VALUE FROM T WHERE MY_PK = 'NO0000000000013');
   RETURNING MY_PK INTO V_Output;
   DBMS_OUTPUT.PUT(V_Output);
 END;

使用以下功能

create or replace FUNCTION NEXT_TRAN_VALUE (field IN VARCHAR2)   RETURN 
VARCHAR2
IS
n_value   VARCHAR2 (20);
P_APR     VARCHAR2(3);

CURSOR rec_exists IS SELECT * FROM TRANSACTION_SEQ where SEQ_NAME = field ;      
jk_seq_rec  TRANSACTION_SEQ%ROWTYPE;   
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
SELECT LC_CODE into P_APR FROM LOCATION_CONFIG;
OPEN rec_exists;
FETCH rec_exists INTO jk_seq_rec;

IF rec_exists%FOUND THEN
    UPDATE TRANSACTION_SEQ SET curr_value =   curr_value + 1 WHERE SEQ_NAME = field;
    COMMIT;
END IF;

--SELECT curr_value INTO n_value FROM TRANSACTION_SEQ WHERE SEQ_NAME = field; 
END;

但是,它显示错误。

select语句应始终返回要插入的单个语句,因此在我看来它应该返回插入行的my_pk

2 个答案:

答案 0 :(得分:1)

那不行。 RETURNING子句不能按照你的方式使用,即

insert into t (id, my_pk)
select some_id, your_function from ...
returning into v_output

但如果您插入VALUES,则可以正常工作

insert into t
values (id, your_function)
returning my_pk into v_output

这意味着您要么必须重写该代码,要么查看returning with insert..select文章(由Adrian Billington撰写)中描述的变通办法

顺便说一下,普通的Oracle序列不适合你的目的吗?不会无间隙,但会很简单&有效。使用您的解决方案在插入大量数据时注意性能。

BTW#2,你函数最后一行的目的是什么?你永远不会使用N_VALUE。

答案 1 :(得分:0)

我使用Cursor来解决问题。