在程序中创建动态表?

时间:2014-08-25 14:06:56

标签: oracle11g

我正在尝试在程序中创建动态表但是我收到错误  告诉我什么是错误

CREATE OR REPLACE PROCEDURE check_sms_bundle_25 (
   MON        VARCHAR2,
   YEAR_P     VARCHAR2 DEFAULT TO_CHAR (SYSDATE, 'YY'),
   QUARTER    VARCHAR2,
   TYPE       VARCHAR2 DEFAULT 'NEW')
IS
BEGIN

   IF UPPER (QUARTER) = 1
   THEN
      EXECUTE IMMEDIATE 'BEGIN CREATE OR REPLACE TABLE (''SMS_Bundle_25_'''|| UPPER (MON)|| '''_Q'''|| UPPER (QUARTER)|| '||''_''||'''|| UPPER (YEAR_P)|| ''')
   AS
   SELECT customer_id, otxact
     FROM ordertrailer INNER JOIN orderhdr_all ON ohxact = otxact
    WHERE sncode = 343 AND ohentdate = ''1-aug-2014'' AND ohstatus = ''IN''
   END';
   END IF;
END;

错误消息是

  

ORA-06550:第2行第4列:PLS-00103:遇到符号   期待以下之一时“创建”:

     如果loop mod null pragma raise,

开始case声明退出goto   使用<<返回选择更新关闭当前删除   fetch lock insert open rollback savepoint set sql execute commit   forall合并管道ORA-06512:在“FI_SDINE.CHECK_SMS_BUNDLE_25”,第9行   ORA-06512:第1行

1 个答案:

答案 0 :(得分:0)

以及'或替换'作为create table syntax的一部分无效,您将DDL语句包含在另一个匿名PL / SQL块中,您试图将表名放在括号内,并且您是包括引号 - 在(未引用的)对象标识符中不允许使用引号。因此,如果您传入争议AUG,14,11 NEW,那么您的动态语句将尝试运行:

BEGIN CREATE OR REPLACE TABLE ('SMS_Bundle_25_'AUG'_Q'1||'_'||'14')
   AS
   SELECT customer_id, otxact
     FROM ordertrailer INNER JOIN orderhdr_all ON ohxact = otxact
    WHERE sncode = 343 AND ohentdate = '1-aug-2014' AND ohstatus = 'IN'
   END

BEGIN / END make是一个块,DDL语句在PL / SQL中无效;这就是为什么你必须首先使用执行立即执行。如果您将构造更改为:

EXECUTE IMMEDIATE 'CREATE TABLE SMS_Bundle_25_'|| UPPER (MON)
  || '_Q'|| UPPER (QUARTER) ||'_' || UPPER (YEAR_P)|| '
   AS
   SELECT customer_id, otxact
     FROM ordertrailer INNER JOIN orderhdr_all ON ohxact = otxact
    WHERE sncode = 343 AND ohentdate = ''1-aug-2014'' AND ohstatus = ''IN''');

然后你试图跑:

CREATE TABLE SMS_Bundle_25_AUG_Q1_14
   AS
   SELECT customer_id, otxact
     FROM ordertrailer INNER JOIN orderhdr_all ON ohxact = otxact
    WHERE sncode = 343 AND ohentdate = '1-aug-2014' AND ohstatus = 'IN'

至少看起来更可行,假设您从中选择的表存在。不知道为什么你将年份和季度数字作为字符串传递或将upper()应用于他们。并且大概你真的希望select在与表名相同的年份和月份进行过滤。

显示您尝试执行的命令非常有用,例如dbms_output,以确切了解您创建的内容;然后你也可以手动运行它以更清楚地看到它出错的地方。

但正如评论中所指出的那样,从这样的程序创建对象是不常见的。您的架构通常应该是静态的,不能动态修改。您无法从其他代码引用此表,除非它也是动态构建的。您似乎正在创建一个表作为其他表的快照;视图或物化视图可能更合适。但是我不确定你为什么要这样做,所以你不应该完全明白你应该做什么。