我有一个在字段上具有NOT NULL约束的数据库,我想删除此约束。复杂的因素是,此约束具有系统定义的名称,并且该约束的名称在生产服务器,集成服务器和各种开发人员数据库之间不同。我们当前的过程是检入变更脚本,并且一个自动化的任务通过sqlplus对目标数据库执行适当的查询,因此我希望可以直接将其发送到sqlplus中的解决方案。
在我自己的数据库上,删除它的SQL将是:
alter table MYTABLE drop constraint SYS_C0044566
查询all_constraints
视图时可以看到约束:
select * from all_constraints where table_name = 'MYTABLE'
但是我不确定如何使用SEARCH_CONDITION
的LONG
数据类型,或者即使知道我的名字也不确定如何最好地动态删除查找的约束。
所以,我如何创建一个更改脚本,可以根据其名称而不是其名称来删除此约束?
编辑:@Allan的答案是一个很好的答案,但我担心(由于我缺乏Oracle专业知识),可能具有系统生成名称的任何约束都可能会与之相关联,这是一种普遍删除的方式,它无需删除任何约束即可必须知道它的名字。确实存在,在逻辑上删除该约束时,总会有一种避免必须知道系统命名约束的名称的方法吗?
alter table MYTABLE modify (MYCOLUMN null);
在Oracle中,当为列指定非null时,会自动创建非null约束。同样,将列更改为允许空值时,它们也会自动删除。
澄清修订后的问题:此解决方案仅适用于为“非空”列创建的约束。如果您在列定义中指定“主键”或检查约束而未命名,则最终将得到系统生成的约束名称(主索引为索引)。在这种情况下,您需要知道要删除的名称。最好的建议是通过确保为除“ not null”以外的所有约束指定一个名称来避免出现这种情况。如果您发现自己通常需要删除这些约束之一,则可能需要使用PL / SQL和数据定义表。
尝试:
alter table <your table> modify <column name> null;
请记住,如果您想使可为空的字段是主键的一部分,则不能。主键不能包含空字段。
要发现使用的任何约束,请使用下面的代码:
-- 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/来自他的Database Design I类。
我在尝试解决自定义检查约束时遇到了相同的问题,我需要对其进行更新以允许使用不同的值。问题在于,ALL_CONSTRAINTS没有办法确定将约束应用于哪个列。我设法做到这一点的方法是查询ALL_CONS_COLUMNS,然后按其名称删除每个约束并重新创建。
选择constraint_name来自all_cons_columns其中table_name = [TABLE_NAME]和column_name = [COLUMN_NAME];
当我将结构的副本复制到临时表时发生了类似的事情,因此我删除了非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;