oracle - 执行立即更改序列不起作用

标签 oracle plsql sequence execute-immediate

我被困在这个非常简单的脚本上。它不像我期望的那样工作。

declare
 st VARCHAR(1024);
begin
  for x in (SELECT sequence_name FROM USER_SEQUENCES) loop
      st := 'ALTER SEQUENCE ' || x.sequence_name ||  ' INCREMENT BY 1000';
      execute immediate st;
      st := 'select ' || x.sequence_name ||  '.nextval from dual';
      execute immediate st;
      st := 'ALTER SEQUENCE ' || x.sequence_name ||  ' INCREMENT BY 1';
      execute immediate st;
  end loop;
end;
/

当我运行它时,它似乎根本不起作用 - 我的所有序列都保持原样,并且它们没有被动态语句增加一千。如果我检查 nextval匿名块前后,相差只有1,而不是1001。

如果我更换 execute immediatedbms_output.put_line并手动执行生成的命令,根据需要更改序列。

我错过了什么?

最佳答案

两者 alter sequence语句正在起作用,它之间的增量没有发生。 nextval循环中的调用没有被评估,因为 select 语句没有将其输出发送到任何地方。来自 the documentation ,恰好是指您正在做的事情的注释:

Note:
If dynamic_sql_statement is a SELECT statement, and you omit both into_clause and bulk_collect_into_clause, then execute_immediate_statement never executes.
For example, this statement never increments the sequence:

EXECUTE IMMEDIATE 'SELECT S.NEXTVAL FROM DUAL'


所以你需要选择那个值:
declare
 st VARCHAR(1024);
 val number;
begin
  for x in (SELECT sequence_name FROM USER_SEQUENCES) loop
      st := 'ALTER SEQUENCE ' || x.sequence_name ||  ' INCREMENT BY 1000';
      execute immediate st;
      st := 'select ' || x.sequence_name ||  '.nextval from dual';
      execute immediate st into val;
      st := 'ALTER SEQUENCE ' || x.sequence_name ||  ' INCREMENT BY 1';
      execute immediate st;
  end loop;
end;
/

我添加了一个 val变量和 into val第二个子句立即执行。

为了证明它现在有效:
create sequence s42;

Sequence s42 created.

declare
 st VARCHAR(1024);
 n number;
begin
  for x in (SELECT sequence_name FROM USER_SEQUENCES) loop
      st := 'ALTER SEQUENCE ' || x.sequence_name ||  ' INCREMENT BY 1000';
      execute immediate st;
      st := 'select ' || x.sequence_name ||  '.nextval from dual';
      execute immediate st into n;
      st := 'ALTER SEQUENCE ' || x.sequence_name ||  ' INCREMENT BY 1';
      execute immediate st;
  end loop;
end;
/

anonymous block completed

select s42.nextval from dual;

   NEXTVAL
----------
      1001 

没有 into子句,返回的是 1 而不是 1001,这就是您所看到的。

关于oracle - 执行立即更改序列不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28701739/

相关文章:

sql - Oracle to_date() 不正确的输出

oracle - 尝试登录时出错 : ORA-12154

oracle - 如何在Oracle plsql block 的一行中声明多个变量

python - 用于计算序列的第 n 个元素的脚本

mysql - Entity Framework 和数据库不可知编程,可能性?

sql - 搜索(在 Oracle 中),使用通配符,无需担心单词出现的大小写或顺序

Oracle PL/SQL 版本 12.2.0.1.0 与 12.1.0.2.0 - 使用参数立即执行

java - 尝试从表中删除行时出错

Clojure无限惰性序列,越界

sql-server - SQL Server 如何确定序列中的下一个值?