Установить значение «Начать с» для последовательности Oracle динамически - PullRequest
4 голосов
/ 11 мая 2010

Я пытаюсь создать сценарий выпуска, который можно развернуть в нескольких базах данных, но где данные могут быть объединены вместе позднее. Очевидный способ справиться с этим - установить порядковые номера для производственных данных достаточно высокими в последующих развертываниях, чтобы предотвратить коллизии.

Проблема заключается в том, чтобы создать скрипт выпуска, который примет номер среды и соответствующим образом установит значение «Начать с» последовательностей. В идеале я хотел бы использовать что-то вроде этого:

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

Это не работает, потому что вы не можете вычислить числовое выражение в DDL.

Другим вариантом является создание последовательностей с использованием динамического SQL через PL / SQL.

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

Однако я бы предпочел избегать этого решения, поскольку я обычно стараюсь избегать выдачи DDL в PL / SQL.

Наконец, третий вариант, который я предложил, - это просто принять значение Start With в качестве переменной подстановки, а не номер среды.

Кто-нибудь лучше подумал, как это сделать?

Ответы [ 3 ]

7 голосов
/ 11 мая 2010

Вы можете использовать синтаксис 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.
4 голосов
/ 11 мая 2010

Если у вас достаточно ограниченное количество баз данных, вы можете запустить последовательности с другими значениями, а затем определить приращение, чтобы значения последовательности не сталкивались. Это исключило бы выражение в начальном значении.

Итак, если у вас есть 10 баз данных:

create sequence seq1 start with &startval increment by 10;

и startval равен 1 для базы данных 1, 2 для базы данных 2 и т. Д.

(Это также устраняет проблему наложения последовательностей, если значения приращения увеличиваются до диапазона следующей базы данных)

1 голос
/ 11 мая 2010

Один из приемов, который я использовал, - это создание сценария 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;
...