动态设置Oracle序列的“Start With”值

时间:2010-05-11 15:23:34

标签: oracle sqlplus

我正在尝试创建一个可以部署在多个数据库上的发布脚本,但是可以在以后将数据合并在一起。处理此问题的显而易见的方法是在后续部署中将生产数据的序列号设置得足够高以防止冲突。

问题在于提供一个发布脚本,该脚本将接受环境编号并适当地设置序列的“Start With”值。理想情况下,我想使用这样的东西:

ACCEPT EnvironNum PROMPT 'Enter the Environment Number:  '
--[more scripting]
CREATE SEQUENCE seq1 START WITH &EnvironNum*100000;
--[more scripting]

这不起作用,因为您无法在DDL中评估数值表达式。

另一种选择是通过PL / SQL使用动态SQL创建序列。

ACCEPT EnvironNum PROMPT 'Enter the Environment Number:  '
--[more scripting]
EXEC execute immediate 'CREATE SEQUENCE seq1 START WITH ' || &EnvironNum*100000;
--[more scripting]

但是,我宁愿避免使用此解决方案,因为我通常会尽量避免在PL / SQL中发出DDL。

最后,我提出的第三个选项就是接受Start With值作为替换变量,而不是环境号。

有没有人更好地考虑如何解决这个问题?

3 个答案:

答案 0 :(得分:7)

您可以使用COLUMN XX NEW_VALUE YY语法在SQL * Plus中执行计算并将结果存储在变量中:

SQL> col sequence_num new_value seq
SQL> select &EnvironNum * 1000000 sequence_num from dual;
Enter value for environnum: 2
old   1: select &EnvironNum * 1000000 sequence_num from dual
new   1: select 2 * 1000000 sequence_num from dual

SEQUENCE_NUM
------------
     2000000

SQL> create sequence scott.seq1 start with &seq;
old   1: create sequence scott.seq1 start with &seq
new   1: create sequence scott.seq1 start with    2000000

Sequence created.

答案 1 :(得分:4)

如果您的数据库数量相当有限,则可以使用不同的值启动序列,然后定义增量以使序列值不会发生冲突。这将消除起始值中的表达式。

所以如果你有10个数据库:

create sequence seq1 start with &startval increment by 10;
对于数据库1,

和startval为1,对于数据库2则为2,等等

(如果增量值增长到下一个数据库的范围,这也消除了序列重叠的问题)

答案 2 :(得分:1)

我使用的一个技巧是从主脚本创建一个sqlplus脚本然后执行它:

可能像

ACCEPT EnvironNum PROMPT 'Enter the Environment Number:  '
spool seq_script.sql
begin
    dbms_output.put_line('CREATE SEQUENCE seq1 START WITH '||&EnvironNum||'*100000;')
end;
spool off
@seq_script.sql

这应该创建一个已经评估过&EnvironNum的脚本文件(假设用户输入'275',例如):

CREATE SEQUENCE seq1 START WITH 275*100000;