是否可以将Insert上的主键返回为select语句-Oracle?

是否可以将Insert上的主键返回为select语句-Oracle?,oracle,oracle-apex,sql-insert,database-trigger,Oracle,Oracle Apex,Sql Insert,Database Trigger,因此,在使用触发器时,我通常会获得新插入记录的主键,如下所示 插入表1 pk1,注释值为空,测试仪返回pk1 进入v_项 我尝试使用相同的概念,但使用select语句插入。例如: 插入表1 pk1,注意选择null,表2中的说明,其中pk2=2返回pk1 进入v_项 注: 1.table1上有一个触发器,它会在插入时自动创建pk1。 2.由于要插入的表的大小,我需要使用select insert。 3.插入基本上是记录的副本,因此一次只插入一条记录 如果我可以提供更多信息,请告诉我。我不相信您可

因此,在使用触发器时,我通常会获得新插入记录的主键,如下所示

插入表1 pk1,注释值为空,测试仪返回pk1 进入v_项

我尝试使用相同的概念,但使用select语句插入。例如:

插入表1 pk1,注意选择null,表2中的说明,其中pk2=2返回pk1 进入v_项

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


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

我不相信您可以直接使用insert/select进行此操作。但是,您可以使用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;

我不相信直接使用insert/select可以做到这一点。但是,您可以使用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;

你不能使用这种机制;铁路图:

returning子句仅在values版本中允许,在子查询版本中不允许

我将您关于“表大小”的第二个限制解释为必须处理的列的数量,可能是作为单个变量,而不是行的数量——我不认为这在这里有什么关系。但是,有一些方法可以避免有很多每列的局部变量;您可以先选择一个行类型变量:

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在我回答这个问题时发布的,所以我不会重复不过,对于一行来说,这可能是过激或过于复杂。

您不能使用这种机制;铁路图:

returning子句仅在values版本中允许,在子查询版本中不允许

我将您关于“表大小”的第二个限制解释为必须处理的列的数量,可能是作为单个变量,而不是行的数量——我不认为这在这里有什么关系。但是,有一些方法可以避免有很多每列的局部变量;您可以先选择一个行类型变量:

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在我回答这个问题时发布的,所以我不会重复不过,对于一行来说,这可能是过激或过于复杂。

您能进一步解释一下您的2个注释吗?我不明白为什么表1太大与问题有关,特别是如果打算在注释3中插入一行的话。不过,我怀疑,如果你注意到了,我向你提出的问题可能会引出一个不应该与这个问题混淆的单独问题。2 2主要是因为3。我不想把所有的列都放在一个顶点页面的一个页面项中,只做一次插入。下面的答案有助于我解决pl/sql循环的问题。你能进一步解释一下你的注释吗?我不明白为什么表1太大与问题有关,特别是如果打算在注释3中插入一行的话。不过,我怀疑,如果你注意到了,我向你提出的问题可能会引出一个不应该与这个问题混淆的单独问题。2 2主要是因为3。我不想把所有的列都放在一个顶点页面的一个页面项中,只做一次插入。下面的答案有助于我解决pl/sql循环的问题。它们都很有效,谢谢,但由于它位于顶部,所以在上面投票:我同意,但可能是我唯一的选择。你可以接受最适合你的答案。我本以为第一个使用rowtype的选项最适合于单行场景,但这是您的代码*8-他们都很有效,谢谢,但由于它位于顶部,所以在上面投票:我同意,但可能是我唯一的选项。您可以接受最适合您的答案。我原以为第一个使用rowtype的选项最适合单行场景,但这是您的代码*8-