我怎样才能删除“not null”当我不知道约束的名称时,Oracle 中的约束?

发布于 2024-08-26 15:04:59 字数 715 浏览 6 评论 0原文

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

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

alter table MYTABLE drop constraint SYS_C0044566

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

select * from all_constraints where table_name = 'MYTABLE'

但我不确定如何使用 SEARCH_CONDITIONLONG 数据类型,或者如何最好地动态删除查找的约束,即使我知道其名称。

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


编辑: @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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

傾旎 2024-09-02 15:05:00
alter table MYTABLE modify (MYCOLUMN null);

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

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

alter table MYTABLE modify (MYCOLUMN null);

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.

怼怹恏 2024-09-02 15:05:00

尝试:

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

Try:

alter table <your table> modify <column name> null;
看海 2024-09-02 15:05:00

请记住,如果您想要设为可为空的字段是主键的一部分,则您不能这样做。
主键不能有空字段。

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.

甜尕妞 2024-09-02 15:05:00

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

-- 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;

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

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

To discover any constraints used, use the code below:

-- 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;

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.

又爬满兰若 2024-09-02 15:05:00

我在尝试绕过自定义检查约束时遇到了同样的问题,我需要更新该约束以允许不同的值。问题是 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];

怪我闹别瞎闹 2024-09-02 15:05:00

当我将结构复制到临时表时,类似的事情发生在我身上,所以我删除了 not 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;

Something like that happened to me when I made copies of structures to temporary tables, so I removed the not 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;
南城旧梦 2024-09-02 15:05:00

如果在创建表时创建了没有名称的列 STATUS 约束,Oracle 会为其分配一个随机名称。不幸的是,我们无法直接修改约束。

删除链接到列 STATUS 的未命名约束所涉及的步骤

  1. 将 STATUS 字段复制到新字段 STATUS2
  2. 在 STATUS2 上定义 CHECK 约束
  3. 将数据从 STATUS 迁移到 STATUS2
  4. 删除 STATUS 列
  5. 将 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

  1. Duplicate STATUS field into a new field STATUS2
  2. Define CHECK constraints on STATUS2
  3. Migrate data from STATUS into STATUS2
  4. Drop STATUS column
  5. 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;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文