Oracle PL/SQL版本12.2.0.1.0与12.1.0.2.0 - 使用参数立即执行

pah*_*han 3 oracle plsql execute-immediate

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

上面给我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
Run Code Online (Sandbox Code Playgroud)

并且无误地工作

   Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
Run Code Online (Sandbox Code Playgroud)

将execute语句更改为以下后,它适用于两个版本,没有任何错误.

 CREATE SEQUENCE  MY_TABLE_ID  MINVALUE 1 MAXVALUE 99999999999999 INCREMENT BY 1 START WITH ' || max_id || '''
Run Code Online (Sandbox Code Playgroud)

这是一个已知的问题?

XIN*_*ING 5

正如@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
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到内部oracle将序列定义保存在某些中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
Run Code Online (Sandbox Code Playgroud)

你现在看到这次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;
Run Code Online (Sandbox Code Playgroud)