当我不知道约束的名称时,如何在Oracle中删除“not null”约束?

时间:2010-03-29 19:17:52

标签: oracle plsql constraints

我有一个对字段有NOT NULL约束的数据库,我想删除这个约束。复杂因素是此约束具有系统定义的名称,并且该约束的名称在生产服务器,集成服务器和各种开发人员数据库之间不同。我们当前的流程是检入更改脚本,自动化任务通过sqlplus对目标数据库执行相应的查询,所以我更喜欢可以直接发送到sqlplus的解决方案。

在我自己的数据库中,删除它的SQL将是:

alter table MYTABLE drop constraint SYS_C0044566

当我查询all_constraints视图时,我可以看到约束:

select * from all_constraints where table_name = 'MYTABLE'

但我不知道如何使用SEARCH_CONDITION的{​​{1}}数据类型,或者即使在我知道其名称后如何最好地动态删除查找的约束。

那么,我如何创建一个可以根据它的内容而不是它的名称来删除此约束的更改脚本?


编辑: @ Allan的答案很好,但我担心(由于我缺乏Oracle的专业知识),任何可能具有系统生成名称的约束都可能与其相关联,这是一种消除约束的方法,这可能并不普遍。不得不知道它的名字。在逻辑上删除该约束时,总是有办法避免必须知道系统命名约束的名称吗?

7 个答案:

答案 0 :(得分:148)

alter table MYTABLE modify (MYCOLUMN null);

在Oracle中,如果未为列指定null,则会自动创建非空约束。同样,当列更改为允许空值时,它们会自动删除。

澄清修订后的问题:此解决方案仅适用于为“非空”列创建的约束。如果在未定义命名的情况下在列定义中指定“主键”或检查约束,则最终将为约束(以及主键的索引)生成系统生成的名称。在这些情况下,您需要知道删除它的名称。最好的建议是通过确保为除“not null”之外的所有约束指定名称来避免该场景。如果您发现自己需要一般地放弃其中一个约束,那么您可能需要求助于PL / SQL和数据定义表。

答案 1 :(得分:16)

尝试:

alter table <your table> modify <column name> null;

答案 2 :(得分:1)

请记住,如果要使其成为可空的字段是主键的一部分,则不能。 主键不能包含空字段。

答案 3 :(得分:1)

要发现使用的任何约束,请使用以下代码:

-- Set the long data type for display purposes to 500000.

SET LONG 500000

-- Define a session scope variable.

VARIABLE output CLOB

-- Query the table definition through the <code>DBMS_METADATA</code> package.

SELECT dbms_metadata.get_ddl('TABLE','[Table Described]') INTO :output FROM dual;

这实际上显示了如何创建引用表的create语句。通过了解表的创建方式,您可以看到所有表约束。

Michael McLaughlin的博客提供的答案:http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/来自他的数据库设计课程。

答案 4 :(得分:0)

我遇到了同样的问题,试图绕过我需要更新的自定义检查约束以允许不同的值。问题是ALL_CONSTRAINTS没有办法告诉哪个列应用了约束。我设法做的方法是通过查询ALL_CONS_COLUMNS,然后按名称删除每个约束并重新创建它。

选择constraint_name 来自all_cons_columns table_name = [TABLE_NAME]  和column_name = [COLUMN_NAME];

答案 5 :(得分:0)

当我将结构的副本复制到临时表时,发生了类似的事情,所以我删除了非null。

DECLARE
   CURSOR cur_temp_not_null IS
        SELECT table_name, constraint_name  FROM all_constraints WHERE table_name LIKE 'TEMP_%' AND  owner='myUSUARIO';

   V_sql VARCHAR2(200); 

BEGIN
  FOR c_not_null IN cur_temp_not_null
   LOOP
     v_sql :='ALTER TABLE ' || c_not_null.table_name || ' DROP CONSTRAINT '|| c_not_null.constraint_name;
     EXECUTE IMMEDIATE  v_sql;     
  END LOOP;
END;

答案 6 :(得分:0)

如果在创建表的过程中在状态STATUS列上创建了约束而没有名称,则Oracle将为其分配一个随机名称。不幸的是,我们不能直接修改约束。

删除与STATUS列关联的未命名约束的步骤

  1. 将STATUS字段复制到新字段STATUS2
  2. 在STATUS2上定义CHECK约束
  3. 将数据从STATUS迁移到STATUS2
  4. “丢弃状态”列
  5. 将STATUS2重命名为STATUS

    A1:Z