执行立即更改序列不工作

Ale*_*kin 3 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;
/
Run Code Online (Sandbox Code Playgroud)

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

如果我更换execute immediatedbms_output.put_line,并执行生成的命令手动序列被改变,因为我想.

我错过了什么?

Ale*_*ole 12

这两个alter sequence陈述都在起作用,这是两者之间没有发生的增量.nextval循环中的调用未被评估,因为select语句没有在任何地方发送其输出.从文档中,一个恰好引用您正在做的事情的注释:

注意:
如果dynamic_sql_statement是一个SELECT语句,并且您省略了into_clausebulk_collect_into_clause,则execute_immediate_statement永远不会执行.
例如,此语句从不递增序列:

EXECUTE IMMEDIATE 'SELECT S.NEXTVAL FROM DUAL'
Run Code Online (Sandbox Code Playgroud)

所以你需要选择那个值:

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;
/
Run Code Online (Sandbox Code Playgroud)

我添加了一个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 
Run Code Online (Sandbox Code Playgroud)

如果没有这个into条款,这将以1而不是1001返回,这就是你所看到的.