首页 文章

在程序中创建动态表?

提问于
浏览
0

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

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:当遇到以下情况之一时遇到符号“CREATE”:如果循环mod为空pragma raise返回选择更新,则使用<< close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe ORA-06512:at“FI_SDINE.CHECK_SMS_BUNDLE_25”,第9行ORA-06512:第1行

1 回答

  • 0

    除了'or replace'作为create table syntax的一部分无效之外,你're enclosing the DDL statement inside another anonymous PL/SQL block, you'试图将表名放在括号内,并且你包括引号 - 这是(未引用的)对象标识符中不允许的 . 因此,如果您传入争议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 . 如果您将构造更改为:

    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 在与表名相同的年份和月份进行过滤 .

    它's useful to display the command you'正在尝试执行,例如使用 dbms_output ,以更清楚地看到你错误地发生了什么 .

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

相关问题