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

时间:2018-05-17 06:53:44

标签: 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;

上执行时,上面给我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

将execute语句更改为以下内容后,它对两个版本都有效,没有任何错误。

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

这是一个已知问题吗?

2 个答案:

答案 0 :(得分: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

你可以在这里看到内部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

你现在看到甲骨文在一些分区中创建了序列,因此在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;

答案 1 :(得分:4)

根据12cR112cR2文档,没有NOPARTITION选项。

该声明确实在12cR1中有效,但似乎默默无视,因为它似乎没有做任何事情 - 尽管它可能在幕后,正如@XING的演示所暗示的那样。并且在12cR2和11gR2中预计会出现错误。

所以这个似乎是12cR1中未记录的(根据MoS搜索)错误,因为当包含无效选项时它不会导致错误。除了......在MoS中有一些点击是间接地将其称为有效,例如错误23210794,其中指定选项显示为变通方法;相反,文档ID 2253744.1提到

  在序列创建过程中使用了

PARTITION / NOPARTITION关键字,这不是12.1功能

有趣的是,all_sequences视图在12cR1中获得了partition_count列,但在12cR2中又丢失了。 (纯粹猜测,但也许这与分区表的自动增量列的内部实现有关,并且实际上并不意味着要为其他序列公开。)

有关更多信息,您需要向Oracle提出服务请求。

但问题的解决方法是从语句中删除NOPARTITION关键字。