【问题标题】:Is it possible to return the Primary Key on an Insert as select statement - Oracle?是否可以将插入的主键作为选择语句返回 - Oracle?
【发布时间】:2023-03-04 02:36:01
【问题描述】:

所以我通常在使用触发器时获取新插入记录的主键如下。

插入 table1 (pk1, notes) 值 (null, "Tester") 返回 pk1 进入 v_item;

我正在尝试使用相同的概念,但使用 select 语句进行插入。比如:

insert into table1 (pk1, notes) select null, description from table2 where pk2 = 2 返回 pk1 进入 v_item;

注意:
1. table1上有一个触发器,它在插入时自动创建一个pk1。
2. 由于要插入的表的大小,我需要使用选择插入。
3.插入基本上是记录的副本,所以一次只插入1条记录。

如果我能提供更多信息,请告诉我。

【问题讨论】:

  • 你能进一步解释你的#2笔记吗?我不明白为什么table1 很大与问题有关,特别是如果目的是插入单行(您的注释#3)。不过,我怀疑我向您提出的问题,如果您注意的话,可能会引出一个单独的问题,不应与这个问题混淆。
  • #2 二主要是因为#3。我不想将所有列放入 Apex 页面中的页面项目中以进行单次插入。下面的答案可以帮助我解决 pl/sql 循环的问题。

标签: oracle oracle-apex sql-insert database-trigger


【解决方案1】:

你不能使用那个机制; as shown in the documentation铁路图:

returning 子句只允许使用值版本,不允许使用子查询版本。

我将您的第二个限制(关于“表格大小”)解释为关于您必须处理的列数,可能作为单个变量,而不是关于行数 - 我不明白这是怎么回事在这里是相关的。不过,有一些方法可以避免每列有很多局部变量;你可以先选择一个行类型的变量:

declare
  v_item number;
  v_row table1%rowtype;
begin
  ...
  select null, description
  into v_row
  from table2 where pk2 = 2;

  insert into table1 values v_row returning pk1 into v_item;

  dbms_output.put_line(v_item);
  ...

或使用循环,如果您真的只有一行,这可能会使事情看起来比必要的更复杂:

declare
  v_item number;
begin
  ...
  for r in (
    select description
    from table2 where pk2 = 2
  )
  loop
    insert into table1 (notes) values (r.description) returning pk1 into v_item;
    dbms_output.put_line(v_item);
    ...
  end loop;
  ...

或收藏......正如@Dan 在我回答这个问题时发布的那样,我不会重复! - 虽然这对于单行来说可能是矫枉过正或过于复杂。

【讨论】:

  • 他们都工作了,谢谢,但投票在上面,因为它在上面:) 我同意,但可能是我唯一的选择。
  • 您可以接受最适合您的答案。我原以为第一个选项(使用 rowtype)最适合单行场景,但这是您的代码 *8-)
【解决方案2】:

我不相信您可以直接使用插入/选择来做到这一点。但是,您可以使用 PL/SQL 和 FORALL 来完成。鉴于表大小的限制,您必须使用l_limit 平衡内存使用和性能。这是一个例子......

鉴于此表有 100 行:

create table t (
  c  number generated by default as identity,
  c2 number
);

insert into t (c2)
select rownum
from dual
connect by rownum <= 100;

你可以这样做:

declare

  cursor t_cur
  is
    select c2
    from t;

  type t_ntt is table of number;

  l_c2_vals_in t_ntt;
  l_c_vals_out t_ntt;
  l_limit      number := 10;

begin

  open t_cur;

  loop
    fetch t_cur bulk collect into l_c2_vals_in limit l_limit;

    forall i in indices of l_c2_vals_in
    insert into t (c2) values (l_c2_vals_in(i))
    returning c bulk collect into l_c_vals_out;

    -- You have access to the new ids here
    dbms_output.put_line(l_c_vals_out.count);

    exit when l_c2_vals_in.count < l_limit;
  end loop;

  close t_cur;

end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    相关资源
    最近更新 更多