更改表,添加列 / 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的主要内容,如果未能解决你的问题,请参考以下文章
“命令行错误:1 列:698 错误报告 - SQL 错误:ORA-00984:此处不允许列