更改表,添加列 / ORA-00984:此处不允许列 PLSQL

Posted

技术标签:

【中文标题】更改表,添加列 / ORA-00984:此处不允许列 PLSQL【英文标题】:Alter table, add column / ORA-00984: column not allowed here 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' 是字符常量 试着说服他这是个坏主意。 【参考方案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' );

谢谢。

【讨论】:

以上是关于更改表,添加列 / ORA-00984:此处不允许列 PLSQL的主要内容,如果未能解决你的问题,请参考以下文章

SQL 错误:ORA-00984:此处不允许列

ORA-00984: 此处不允许列 - 动态 SQL

PL/SQL 错误:ORA-00984 此处不允许列

“命令行错误:1 列:698 错误报告 - SQL 错误:ORA-00984:此处不允许列

操作Oracle数据库,插入数据时显示:ORA-00984列在此处不允许错误

SQL Server中如何不允许列重复?