我被困在这个非常简单的脚本上。它不像我期望的那样工作。
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 immediate
与 dbms_output.put_line
并手动执行生成的命令,根据需要更改序列。我错过了什么?
最佳答案
两者 alter sequence
语句正在起作用,它之间的增量没有发生。 nextval
循环中的调用没有被评估,因为 select 语句没有将其输出发送到任何地方。来自 the documentation ,恰好是指您正在做的事情的注释:
Note:
If dynamic_sql_statement is aSELECT
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/