我怎样才能删除“not null”当我不知道约束的名称时,Oracle 中的约束?
我有一个数据库,其字段上有 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 专业知识),任何可能具有系统生成名称的约束都将与其关联一种无需删除约束的方法,这可能并不普遍正确。必须知道它的名字。在逻辑上删除该约束时,是否总是有一种方法可以避免必须知道系统命名的约束的名称?
I have a database which has a NOT NULL constraint on a field, and I want to remove this constraint. The complicating factor is that this constraint has a system-defined name, and that constraint's name differs between the production server, integration server, and the various developer databases. Our current process is to check in change scripts, and an automated task executes the appropriate queries through sqlplus against the target database, so I'd prefer a solution that could just be sent straight into sqlplus.
On my own database, the SQL to drop this would be:
alter table MYTABLE drop constraint SYS_C0044566
I can see the constraint when I query the all_constraints
view:
select * from all_constraints where table_name = 'MYTABLE'
but I am not sure how to work with the SEARCH_CONDITION
's LONG
data type or how best to dynamically delete the looked-up constraint even after I know its name.
So, how can I create a change script that can drop this constraint based on what it is, rather than what its name is?
EDIT:
@Allan's answer is a good one, but I am concerned (in my lack of Oracle expertise) that it may not be universally true that any constraint that might have a system-generated name will have associated with it a way to remove the constraint without having to know its name. Is it true that there will always be a way to avoid having to know a system-named constraint's name when logically dropping that constraint?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在 Oracle 中,当为列指定 not null 时,会自动创建 not null 约束。同样,当列更改为允许空值时,它们会自动删除。
澄清修订后的问题:此解决方案仅适用于为“not null”列创建的约束。如果您在列定义中指定“主键”或检查约束但未命名,则最终会得到系统生成的约束名称(以及主键的索引名称)。在这些情况下,您需要知道名称才能删除它。最好的建议是通过确保为除“not null”之外的所有约束指定名称来避免这种情况。如果您发现自己处于一般需要放弃这些约束之一的情况,则可能需要求助于 PL/SQL 和数据定义表。
In Oracle, not null constraints are created automatically when not null is specified for a column. Likewise, they are dropped automatically when the column is changed to allow nulls.
Clarifying the revised question: This solution only applies to constraints created for "not null" columns. If you specify "Primary Key" or a check constraint in the column definition without naming it, you'll end up with a system-generated name for the constraint (and the index, for the primary key). In those cases, you'd need to know the name to drop it. The best advice there is to avoid the scenario by making sure you specify a name for all constraints other than "not null". If you find yourself in the situation where you need to drop one of these constraints generically, you'll probably need to resort to PL/SQL and the data-definition tables.
尝试:
Try:
请记住,如果您想要设为可为空的字段是主键的一部分,则您不能这样做。
主键不能有空字段。
Just remember, if the field you want to make nullable is part of a primary key, you can't.
Primary Keys cannot have null fields.
要发现所使用的任何约束,请使用以下代码:
这实质上显示了如何创建引用表的创建语句。通过了解表的创建方式,您可以看到所有表约束。
答案取自 Michael McLaughlin 的博客: http://michaelmclaughlin .info/db1/lesson-5-querying-data/lab-5-querying-data/ 来自他的数据库设计 I 课程。
To discover any constraints used, use the code below:
This essentially shows a create statement for how the referenced table is made. By knowing how the table is created, you can see all of the table constraints.
Answer taken from Michael McLaughlin's blog: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ From his Database Design I class.
我在尝试绕过自定义检查约束时遇到了同样的问题,我需要更新该约束以允许不同的值。问题是 ALL_CONSTRAINTS 无法判断约束应用于哪一列。我设法做到这一点的方法是查询 ALL_CONS_COLUMNS,然后按名称删除每个约束并重新创建它。
选择约束名称
来自 all_cons_columns
其中表名 = [表名]
和列名 = [COLUMN_NAME];
I was facing the same problem trying to get around a custom check constraint that I needed to updated to allow different values. Problem is that ALL_CONSTRAINTS does't have a way to tell which column the constraint(s) are applied to. The way I managed to do it is by querying ALL_CONS_COLUMNS instead, then dropping each of the constraints by their name and recreate it.
select constraint_name
from all_cons_columns
where table_name = [TABLE_NAME]
and column_name = [COLUMN_NAME];
当我将结构复制到临时表时,类似的事情发生在我身上,所以我删除了 not null。
Something like that happened to me when I made copies of structures to temporary tables, so I removed the not null.
如果在创建表时创建了没有名称的列 STATUS 约束,Oracle 会为其分配一个随机名称。不幸的是,我们无法直接修改约束。
删除链接到列 STATUS 的未命名约束所涉及的步骤
将 STATUS2 重命名为 STATUS
更改表 MY_TABLE 添加状态2 NVARCHAR2(10) 默认“打开”;
ALTER TABLE MY_TABLE 添加约束 MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED'));
更新我的表集状态2 = 状态;
更改表 MY_TABLE 删除列状态;
ALTER TABLE MY_TABLE 将列 STATUS2 重命名为 STATUS;
If constraint on column STATUS was created without a name during creating a table, Oracle will assign a random name for it. Unfortunately, we cannot modify the constraint directly.
Steps involved of dropping unnamed constraint linked to column STATUS
Rename STATUS2 to STATUS
ALTER TABLE MY_TABLE ADD STATUS2 NVARCHAR2(10) DEFAULT 'OPEN';
ALTER TABLE MY_TABLE ADD CONSTRAINT MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED'));
UPDATE MY_TABLE SET STATUS2 = STATUS;
ALTER TABLE MY_TABLE DROP COLUMN STATUS;
ALTER TABLE MY_TABLE RENAME COLUMN STATUS2 TO STATUS;