【问题标题】:Alter table, add column / ORA-00984: column not allowed here PLSQL更改表,添加列 / ORA-00984:此处不允许列 PLSQL
【发布时间】:2016-09-28 13:53:17
【问题描述】:

下一条语句 SQL 给我一个“ORA-00984: column not allowed here”:

ALTER TABLE USUVCB.TVCB_RUT_SII ADD (Fecha_Inicio VARCHAR2(10 BYTE) DEFAULT TO_CHAR(SYSDATE, "YYYY-MM-DD") NOT NULL);

它变成了一个 PL-SQL,像这样:

SET SERVEROUTPUT ON

DECLARE
Fecha VARCHAR2(8) := TO_CHAR (SYSDATE, 'YYYYMMDD');
Tabla VARCHAR2(28) := 'USER.TABLE_' || Fecha;
BEGIN
    SAVEPOINT START;
    BEGIN
        EXECUTE IMMEDIATE 'CREATE TABLE ' || Tabla || ' AS SELECT FIELD_1, FIELD_2, FIELD_3 FROM USER.TABLE';
    EXCEPTION
        WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
        DBMS_OUTPUT.PUT_LINE('Error creating the table');
    END;

    BEGIN
        EXECUTE IMMEDIATE 'ALTER TABLE USER.TABLE ADD (FIELD_4 VARCHAR2(10 BYTE) DEFAULT TO_CHAR (SYSDATE, "YYYY-MM-DD") NOT NULL)';
    EXCEPTION
        WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
        DBMS_OUTPUT.PUT_LINE('Error creating the field');
    END;

    BEGIN
        ...
    EXCEPTION
        WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
        DBMS_OUTPUT.PUT_LINE('...');
    END;
EXCEPTION
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Rollback');
    ROLLBACK TO START;
END;

我希望它能够捕获 PL-SQL 中发生的所有异常,以便在出现任何错误时在检查点 START 处回滚。

【问题讨论】:

  • 你为什么要添加一个DATE 列作为VARCHAR?
  • 事务(即ROLLBACK)对您没有帮助,因为每个 DDL 命令在执行时会隐含COMMIT
  • 您将永远无法到达DBMS_OUTPUT.PUT_LINE('Rollback'); 行,因为之前已处理所有异常。
  • 字符串/字符值需要用单引号括起来。 "YYYY-MM-DD" 是标识符,'YYYY-MM-DD' 是字符常量
  • 试着说服他这是个坏主意。

标签: sql oracle plsql oracle11g alter


【解决方案1】:

格式掩码需要使用单引号:

ALTER TABLE USUVCB.TVCB_RUT_SII ADD (Fecha_Inicio VARCHAR2(10 BYTE) DEFAULT TO_CHAR(SYSDATE, 'YYYY-MM-DD') NOT NULL);

在执行中,这将是:

execute immediate 'ALTER TABLE USUVCB.TVCB_RUT_SII ADD (Fecha_Inicio VARCHAR2(10 BYTE) DEFAULT TO_CHAR(SYSDATE, ''YYYY-MM-DD'') NOT NULL)';

请注意,您正在执行 DDL 查询,因此您将无法回滚所做的修改。回滚只影响数据,而不影响结构。

此外,为什么要将日期存储在varchar 列中?这是个坏主意,最好是date 专栏

【讨论】:

  • 我将日期存储到 varchar 中,以便可以将其用于备份表的名称。如果出现错误,是否可以回滚?
  • 回滚不是办法。一种简单的方法是为您执行的每个语句构建一个还原语句,将它们存储在某个变量中,然后在出现错误时运行它们
  • 在这种情况下,我可以捕捉到外部异常中发生的任何错误吗?
  • 你可以用任何你需要的方式处理异常;你可以简单地用扫描语句数组并运行它们来替换你的回滚
  • 你只需要处理字符串中的单引号;刚刚给你指路了
【解决方案2】:

Aleksej 有一个很好的解决方案。 Oracle 的一个经常被忽视的特性是 q 引用。通过使用此功能,您可以使用单引号。这是与 q 引用相同的答案:

EXECUTE immediate q'[ALTER TABLE USUVCB.TVCB_RUT_SII ADD (Fecha_Inicio VARCHAR2(10 BYTE) DEFAULT TO_CHAR(SYSDATE, 'YYYY-MM-DD') NOT NULL)]';

【讨论】:

    【解决方案3】:

    我得到了解决方案:

    我正在使用

    ALTER TABLE PG_PGS_MST_LABEL MODIFY (LANG_CODE DEFAULT EN );

    但是

    我的解决方案是 Lang_CODE 列是 varchar2,我必须在 EN 中使用单个代码,即

    ALTER TABLE PG_PGS_MST_LABEL  MODIFY (LANG_CODE DEFAULT 'EN' );
    

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 2018-11-16
      • 2013-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多