1

数据库版本:Oracle 11.2.0.2

场景:尝试使用过程自动创建范围分区。下面是代码。它被创建没有任何错误。但是当我执行时,它会抛出一个错误。我认为传递给变量的值不正确。我尝试了各种 sql,但没有任何效果。有人可以帮我完成这个过程。

SQL> CREATE OR REPLACE PROCEDURE MONTHLY_PARTITION as
  2
  3    v_partition_name varchar2(30);
  4    v_limit TIMESTAMP with local time zone;

  5    6  begin
  7
  8    select to_char(trunc(add_months(sysdate,1),'MM'),'MonYYYY')
  9    into v_partition_name
 10    from dual;
 11
 12    SELECT TO_TIMESTAMP(TO_CHAR(ADD_MONTHS(current_timestamp, 2), 'YYYYMMDD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')  into v_limit from dual;
 13
 14  execute immediate 'ALTER TABLE TEST ADD PARTITION ' || v_partition_name || ' VALUES LESS    THAN (TIMESTAMP ' || v_limit || ')';
 15
 16  end;
 17  /

Procedure created.

SQL> show errors
No errors.
SQL>
SQL> exec MONTHLY_PARTITION;
BEGIN MONTHLY_PARTITION; END;

*
ERROR at line 1:
ORA-14019: partition bound element must be one of: string, datetime or interval literal, number, or MAXVALUE
ORA-06512: at "MONTHLY_PARTITION", line 14
ORA-06512: at line 1
4

3 回答 3

2

你所拥有的其实还可以。只是一些数据类型错误而已!

在将其拼接到 DDL 时,您必须将变量作为varchar2而不是。timestamp

IE:

SQL> create table TEST(dte timestamp)
  2  partition by range (dte)
  3  (PARTITION TODAY VALUES LESS THAN (TIMESTAMP'2012-02-01 00:00:00'));

Table created.

SQL> CREATE OR REPLACE PROCEDURE MONTHLY_PARTITION as
  2
  3   v_partition_name varchar2(30);
  4   v_limit varchar2(30);
  5
  6    begin
  7
  8   select to_char(trunc(add_months(sysdate,1),'MM'),'MonYYYY')
  9   into v_partition_name
 10   from dual;
 11
 12   SELECT TO_CHAR(ADD_MONTHS(current_timestamp, 2), 'YYYY-MM-DD HH24:MI:SS')  into v_limit from dual;
 13
 14  execute immediate 'ALTER TABLE TEST ADD PARTITION ' || v_partition_name || ' VALUES LESS THAN (TIMESTAMP''' || v_limit || ''')';
 15
 16  end;
 17  /

Procedure created.

SQL> exec monthly_partition

PL/SQL procedure successfully completed.

SQL> select partition_name from user_tab_partitions where table_name = 'TEST';

PARTITION_NAME
------------------------------
TODAY
MAR2013

另请注意,您当前的表达式ADD_MONTHS(current_timestamp, 2)不会截断为月份。你也想这样做吗?即trunc(ADD_MONTHS(current_timestamp, 2), 'mm')

于 2013-02-06T00:18:02.910 回答
1

将此分配给字符串变量:

    str := 'ALTER TABLE TEST ADD PARTITION ' || v_partition_name 
       || ' VALUES LESS THAN (TIMESTAMP ' || v_limit 
       || ')';

然后

dbms_output.PUT_LINE( str );
execute immediate str;

查看输出 str 是否会按照您的预期从 sql plus 运行

于 2013-02-05T21:53:37.560 回答
0

分区值必须是固定的,必须手动处理。指定分区值时不能有表达式。

于 2013-02-05T21:53:01.963 回答