一个查询中的seq_name.nextval相同。 ORACLE

时间:2013-03-26 13:18:11

标签: sql oracle

如何在一个查询中两次选择相同的序列?

我用谷歌搜索了这个并且无法得到答案。

为了清楚起见,这就是我需要的,例如:

select seq.nextval as v1, seq.nextval as v2 from dual(我知道这不起作用)

我也尝试过UNION,只是无法理解它。

5 个答案:

答案 0 :(得分:3)

如果您总是需要两个值,则可以将序列更改为2:

alter sequence seq increment by 2;

然后选择当前值及其后续值:

select seq.nextval,
 seq.nextval + 1
 from dual;

不漂亮,但应该可以胜任。

<强>更新

只是为了澄清:ALTER SEQUENCE一生只能发一次,而不是每次发布一次!

答案 1 :(得分:2)

弗兰克的答案有一个缺点:

  

您无法在事务系统中使用它,因为ALTER SEQUENCE会提交任何待处理的DML。

肖恩的回答只拉了一次序列。 据我所知,你想要拉两个值。 作为Seans解决方案的替代方案,您还可以从.nextval中选择两次,因为ORACLE会为您提供两次相同的值。

我更喜欢在程序中包装序列。 这欺骗了oracle两次拉序列。

CREATE or replace FUNCTION GetSeq return number as

nSeq NUMBER;

begin

select seq.nextval into nSeq from dual;

return nSeq;

end;
/

如果你一般需要这个,也许你想要:

CREATE or replace FUNCTION GetSeq(spSeq in VARCHAR2) return number as

nSeq NUMBER;
v_sql long;

begin

v_sql:='select '||upper(spSeq)||'.nextval from dual';
execute immediate v_sql into nSeq;

return nSeq;

end;
/

答案 2 :(得分:1)

NEXTVAL的使用方式存在一些限制。有一个列表in the Oracle docs。更重要的是,该链接包括一个不止一次调用NEXTVAL的条件列表。

在页面上命名的唯一场景,其中直接SELECT将多次调用NEXTVAL“顶级SELECT语句”中。将调用NEXTVAL两次的粗略查询是:

SELECT seq.NEXTVAL FROM (
  SELECT * FROM DUAL
  CONNECT BY LEVEL <= 2) -- Change the "2" to get more sequences

不幸的是,如果您尝试将其推入子查询以将值展平为列v1v2(如您的问题中),那么您将获得{{1 }}

这是我能得到的尽可能接近。如果上述查询无法帮助您获得所需内容,请查看此处发布的其他答案。正如我一直打字一样,已经发布了几个很好的答案。

答案 3 :(得分:1)

告诉你多次调用sequence.nextval会很无聊,所以这是你可以尝试的:

create type t_num_tab as table of number;

CREATE SEQUENCE SEQ_TEST
  START WITH 1
  MAXVALUE 999999999999999999999999999
  MINVALUE 1
  NOCYCLE
  CACHE 100
  NOORDER;

create or replace function get_seq_vals(i_num in number) return t_num_tab is 
    seq_tab t_num_tab;
begin

select SEQ_TEST.nextval
bulk collect into seq_tab
from all_objects
where rownum <= i_num;

return seq_tab;

end;

您可以按如下方式使用它。这个例子是从序列中一次拉出7个数字:

declare
    numbers t_num_tab;
    idx number;
begin
    -- this grabs x numbers at a time
    numbers := get_seq_vals(7);

    -- this just loops through the returned numbers
    -- to show the values
    idx := numbers.first;
    loop
        dbms_output.put_line(numbers(idx));
        idx := numbers.next(idx);
        exit when idx is null;
    end loop;
end;

另请注意,我使用“next”而不是first..last,因为您可能希望在迭代之前从列表中删除数字(或者,有时序列缓存可能导致数字递增超过1)。

答案 4 :(得分:0)

这些都是很好的答案,遗憾的是它还不够。在将来挣扎的时候肯定能够回到这个页面。

我选择了另一种方法。问了一个新问题并得到了答案。

您可以查看here