【问题标题】:Write an insert statement with select clause returning id in oracle在 oracle 中编写一个带有 select 子句返回 id 的插入语句
【发布时间】:2018-03-07 05:05:13
【问题描述】:

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

例如:

 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

【问题讨论】:

  • 谷歌搜索了很多论坛后,我发现,大多数人都说这是不可能的。我宁愿将值存储到局部变量并使用它们重新插入。但是,我有很多相互链接的子表,所以,这样做会很忙。
  • 该功能似乎毫无意义,因为您在那里丢失的数字与序列相同(因为您正在提交更新)。但是一个序列会更快,并且会更好地扩展

标签: sql oracle plsql


【解决方案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 序列不适合您的目的吗?不会是无缝的,但会简单有效。使用您的解决方案插入大量数据时注意性能。

顺便说一句#2,你函数中最后一行的目的是什么?你从不使用 N_VALUE。

【讨论】:

  • 是的,oracle 序列适合这个目的,使用这个功能是没有意义的。但是,当我将数据库迁移到另一台机器时,oracle 序列重新启动序列并让我头疼(它找到最低的最小缺失值并从它们开始序列),并且它们的功能开始发挥作用。最后一行 N_Value 的使用没什么。它只是懒惰的编码。
  • “迁移重置序列”是什么意思?这是一种怎样的迁移?无论如何,我宁愿将序列放在新机器上并重新创建它(使用start with,这将是旧系统的currval + 1)。是的,它需要 2 个额外的语句(selectcreate sequence),但将来会得到回报。
  • 我是 Oracle 数据库的新手。我发现nextval 是增加价值的唯一选择,我没有遇到currval + 1,也许它可以解决我的问题。但我发现当时有一个功能值得。此外,它们都对我当前的问题没有用处。
  • 好的,没问题。我只是分享我的观点,你不必接受。
  • @Littlefoot 当一个人被限制使用select 而不是values 时,是否有解决方法?
【解决方案2】:

我使用Cursor 来解决问题。

【讨论】:

  • 有趣的想法。你能举个例子吗?谢谢
猜你喜欢
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多