Oracle PL/SQL Release 12.2.0.1.0 vs 12.1.0.2.0 — немедленное выполнение с параметрами

DECLARE
  max_id INTEGER;
BEGIN
  SELECT MAX(ID) + 1 INTO max_id FROM MY_TABLE;

  EXECUTE IMMEDIATE 'CREATE SEQUENCE  MY_TABLE_ID  MINVALUE 1 MAXVALUE 99999999999999 INCREMENT BY 1 START WITH ' || max_id || ' CACHE 100 NOORDER  NOCYCLE  NOPARTITION';

END;

Выше дает мне ORA-00933: SQL command not properly ended при выполнении

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production

и работает без ошибок на

   Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production

После того, как я изменил оператор выполнения на приведенный ниже, он работает в обеих версиях без каких-либо ошибок.

 CREATE SEQUENCE  MY_TABLE_ID  MINVALUE 1 MAXVALUE 99999999999999 INCREMENT BY 1 START WITH ' || max_id || '''

Это известная проблема?


person pahan    schedule 17.05.2018    source источник
comment
Непонятно где работает, а где нет, так как вы два раза выложили 12.2.0.1.0 (и в не работает и работает).   -  person Littlefoot    schedule 17.05.2018
comment
@Littlefoot Обновил вопрос   -  person pahan    schedule 17.05.2018
comment
Вы отредактировали сообщение, но 12.2.0.1.0 по-прежнему стоит в обоих утверждениях. Посмотрите поближе.   -  person Littlefoot    schedule 17.05.2018
comment
@Littlefoot Очень сожалею об этом. Исправлено сейчас   -  person pahan    schedule 17.05.2018


Ответы (2)


В соответствии с 12cR1 или 12cR2.

Статус действительно работает в 12cR1, но, похоже, молча игнорируется, поскольку он ничего не делает - хотя он может быть под капотом, как предполагает демонстрация @XING. А это ошибки ожидаются в 12cR2 и 11gR2.

Таким образом, похоже, это недокументированная (согласно поиску MoS) ошибка в 12cR1, поскольку она не вызывает ошибки при включении недопустимой опции. За исключением... в MoS есть несколько обращений, которые косвенно ссылаются на него как на действительный, например. ошибка 23210794, где указание опции показано как обходной путь; наоборот, в документе ID 2253744.1 упоминается

При создании последовательности использовалось ключевое слово PARTITION/NOPARTITION, которое не является функцией версии 12.1.

Интересно, что представление all_sequences получило столбец partition_count в 12cR1, но затем снова потерял его в 12cR2. (Чисто предположение, но, возможно, это связано с внутренней реализацией столбцов автоинкремента для секционированных таблиц и не предназначено для использования в других последовательностях.)

Для получения дополнительной информации вам необходимо отправить запрос на обслуживание в Oracle.

Но решение вашей проблемы заключается в удалении ключевого слова NOPARTITION из вашего заявления.

person Alex Poole    schedule 17.05.2018

Как упоминал @Alex, создание последовательности с предложением Partition является недокументированной функцией, такой как WMCONCAT. См. объяснение ниже:

sql> create sequence s1;

Sequence created.

sql> select s1.nextval from dual;

     NEXTVAL
     ---------
     1

sql> select dbms_metadata.get_ddl('SEQUENCE','S1') from dual;

DBMS_METADATA.GET_DDL('SEQUENCE','S1')
--------------------------------------------------------------------------------

 CREATE SEQUENCE  "SCOTT"."S1"  MINVALUE 1 MAXVALUE 99999999999999999999999999
99 INCREMENT BY 1 START WITH 21 CACHE 20 NOORDER  NOCYCLE  NOPARTITION

Здесь вы можете видеть, что внутри оракула сохраняется определение последовательности в некотором partition и, следовательно, оно отображается в DDL.

Создать другую последовательность

sql> create sequence s2 partition;

  Sequence created.

sql> select s2.nextval from dual;

     NEXTVAL
---------------
      4103920000000000000000000000000001

sql> select dbms_metadata.get_ddl('SEQUENCE','S2') from dual;

DBMS_METADATA.GET_DDL('SEQUENCE','S2')
--------------------------------------------------------------------------------

 CREATE SEQUENCE  "SCOTT"."S2"  MINVALUE 1 MAXVALUE 99999999999999999999999999
99 INCREMENT BY 1 START WITH 21 CACHE 20 NOORDER  NOCYCLE  PARTITION 100000000

Вы видите, что на этот раз Oracle создал последовательность в каком-то разделе и, следовательно, показал это в определении DDL.

Некоторые функции Oracle зарезервированы для собственного внутреннего использования, поэтому они не документированы.

В вашем случае, если вы удалите эту часть, другая часть будет работать нормально. Смотри ниже:

DECLARE
  max_id INTEGER;
BEGIN
  SELECT MAX(ID) + 1 INTO max_id FROM MY_TABLE;

  EXECUTE IMMEDIATE 'CREATE SEQUENCE  MY_TABLE_ID  MINVALUE 1 MAXVALUE 99999999999999 INCREMENT BY 1 START WITH '|| max_id||'  CACHE 100 NOORDER  NOCYCLE  ' ;
END;
person XING    schedule 17.05.2018