【问题标题】:Stored procedure to return a list of sequence IDs返回序列 ID 列表的存储过程
【发布时间】:2010-12-02 06:29:40
【问题描述】:

我需要一个小存储过程来执行以下逻辑?

procedure_name(seq_name IN varchar2(50), block_count IN int, return_ids OUT)

从 1 循环到 block_count
return_ids := select 'seq_name'||.nextVal from dual;
结束循环
返回 return_ids

基本上我想要做的是有一个存储过程,它让我可以传入一个序列名称、我需要多少个 ID,并将生成的 ID 列表返回给我,这些 ID 可以在 JAVA 中使用。这样做的原因是返回一个我可以在 JAVA 中使用的 ID 列表,并且没有其他人使用这些序列 ID。它们将在以后的一些其他批量插入中使用。本质上,保留一个序列 ID 块。

【问题讨论】:

    标签: plsql oracle9i


    【解决方案1】:

    这是从 PL/SQL 过程返回数组的一种方法。

    创建一个数字集合类型,在您的过程中对其进行初始化,并用要返回的数字填充它。例如:

    create or replace type narray as table of number;
    
    create or replace procedure get_seq_ids(seq_name in varchar2, 
        block_count in number, return_ids out narray)
    as
    begin
        return_ids := narray();
        return_ids.extend(block_count);
        for i in 1 .. block_count
        loop
            execute immediate 'select ' || seq_name || '.nextval from dual' 
                into return_ids(i);
        end loop;
    end;
    /
    

    【讨论】:

    • 感谢 vls,这正是我所需要的!
    【解决方案2】:

    我会担心在将记录插入数据库之前需要生成 ID 的逻辑。

    或者,您可能需要考虑先插入行,从行中选择 ID,然后使用更新语句进行批量操作。然而,这仍然不如在实际信息准备好插入之前让 Java 代码不依赖于 id 那样可取。

    您可以将您的信息推送到 XML(或您的数据库可以理解的任何其他数据格式)中,然后调用存储过程来进行批量插入。

    【讨论】:

    • 好吧,如果我有 DBA 支持,那么我宁愿只是将数组传递给一个过程,让它们处理 DB 端的所有插入。但是由于我没有支持...
    • 我正在尝试将大量记录插入到相关的分层表中。因为我需要顶级表中的 ID,所以我可以将其插入到二级表中,依此类推到三级和四级表中,依此类推。我也不想每次插入时都使用 JDBC 调用数据库来获取 ID。我只想预取一个可以填充各种数组的 SEQ_ID 块,这样我就可以在批量插入中使用这些数组。
    • 我对您关于没有 DBA 支持的评论感到困惑。您可以编写存储过程来保留 ID,但不能编写存储过程来插入具有正确 ID 的每个表?
    • 这不是一个不寻常的问题。 Java 提供了一个批处理命令,可以在一次调用中发出一系列 DML 操作。利用这一点的唯一方法是提前获取 ID,以便可以在插入任何行之前指定所有外键引用
    • 与通过 XML 将数据发送到可以本地处理密钥的存储过程相比,Java 批处理命令有什么好处?我可以在 XML 中“批处理”命令而不是数组来进行一次调用。
    【解决方案3】:

    另一种选择可能是使用RETURNING 子句在插入后自动返回序列值。

    【讨论】:

      【解决方案4】:

      恕我直言,您能做的最好的事情就是在 INSERT INTOVALUES 子句中引用 sequence_name.nextval

      您说过要避免其他人使用相同的 ID。引用this site

      序列(或 Oracle,就此而言)确保在同一会话中没有其他会话或对 nextval 的其他调用从序列中获得相同的编号。

      因此,Oracle 中保证了序列号的唯一性。

      【讨论】:

      • 问题在于出于性能原因想要批量处理 DML 操作的应用程序,将 nextval 调用留在 INSERT 中意味着后续查询在插入任何子记录之前获取该 ID。对于一个必须持久保存很多行的应用程序,这需要与数据库进行大量的来回交谈。
      【解决方案5】:

      这是我为我支持的 Java 应用程序所做的(它还使用批量插入到深度分层的表中)

      PROCEDURE get_nextvals
      ( 
          p_values OUT SYS_REFCURSOR,
          p_count  IN  PLS_INTEGER
      )
      IS
          -- return the next p_count values from the PK sequence
      BEGIN
          OPEN p_values FOR
              SELECT
                  <schema>.<sequence>.nextval
              FROM
                  dual
              CONNECT BY
                  LEVEL <= p_count
          ;
      END;
      

      将游标传递给 java 比让应用使用数据库中定义的表类型更容易。

      【讨论】:

      • 也很有帮助,我得到了表格类型的工作方式,但我会尝试这种方式,看看它是否有所作为。谢谢大家!
      猜你喜欢
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      • 2011-02-20
      • 2015-08-12
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 2021-10-06
      相关资源
      最近更新 更多