【问题标题】:Difference BETWEEN adding CHECK ON a COLUMN AND CHECK CONSTRAINT ON THE same COLUMN在列上添加检查和在同一列上检查约束之间的差异
【发布时间】:2019-12-17 13:30:24
【问题描述】:

在使用 XML 比较表结构时,我们发现检查约束的相同业务逻辑的表结构有所不同。 请检查并解释我们的区别。

CREATE TABLE ESWAR(ID INT NOT NULL, NAME VARCHAR2(10));

ALTER TABLE ESWAR ADD CHECK("NAME" IS NOT NULL);

添加检查后的表定义:

create table ESWAR
(
  id   INTEGER not null,
  name VARCHAR2(10) not null
);

删除创建的系统约束

SELECT T.CONSTRAINT_NAME FROM ALL_Constraints t WHERE t.TABLE_NAME='ESWAR' AND T.SEARCH_CONDITION_VC='"NAME" IS NOT NULL';--SYS_C00179403

ALTER TABLE ESWAR DROP CONSTRAINT SYS_C00179403;

再次创建检查约束如下

ALTER TABLE ESWAR
  ADD CONSTRAINT CONST_ESWAR_CHECK
  CHECK ("NAME" IS NOT NULL);

创建约束后的表定义:

create table ESWAR
(
  id   INTEGER not null,
  name VARCHAR2(10)
);

-- Create/Recreate check constraints 
alter table ESWAR
  add constraint CONST_ESWAR_CHECK
  check ("NAME" IS NOT NULL);

SELECT * FROM ALL_Constraints t WHERE t.TABLE_NAME='ESWAR' AND T.SEARCH_CONDITION_VC='"NAME" IS NOT NULL';---CONST_ESWAR_CHECK

【问题讨论】:

  • 当您说“对列添加检查”时,实际上是在添加检查约束。没有“支票”之类的东西。
  • 对于非空检查约束的特定情况,基本的NOT NULL 优于显式检查约束,因为优化器知道NOT NULL 列但不查看其他用户定义的列检查约束定义。
  • 我同意 William Robertson 的观点,但我主要关心的是为什么表定义会变得不同。
  • 到底有什么不同?在我的测试中,我可以创建任意数量的匿名(系统命名)检查约束,如(NAME IS NOT NULL)("NAME" IS NOT NULL),并且它们都没有使列在标准的、有用的意义上实际上不为空。否则,唯一的区别是名称,如果您自己命名,则为 CONST_ESWAR_CHECK,否则为系统生成。你提到了 XML,但我没有看到。

标签: sql oracle constraints ddl


【解决方案1】:

考虑:

ALTER TABLE ESWAR ADD CHECK("NAME" IS NOT NULL);

ALTER TABLE ESWAR ADD CONSTRAINT CONST_ESWAR_CHECK CHECK ("NAME" IS NOT NULL);

约束在功能上是相同的;但是,将使用系统生成的名称(即SYS_C00179403)生成一个,而另一个将使用用户定义的名称(即CONST_ESWAR_CHECK)生成。

如果您在 CREATE TABLE 语句中创建 constraint in-line,则可以使用完全相同的选项:

CREATE TABLE ESWAR(
  ID   INT          NOT NULL PRIMARY KEY,
  NAME VARCHAR2(10) NOT NULL
);

CREATE TABLE ESWAR(
  ID   INT          NOT NULL PRIMARY KEY,
  NAME VARCHAR2(10) CHECK( NAME IS NOT NULL )
);

CREATE TABLE ESWAR(
  ID   INT
       CONSTRAINT ESWAR__ID__NN NOT NULL
                                INITIALLY IMMEDIATE
                                NOT DEFERRABLE
                                ENABLE
                                VALIDATE
       CONSTRAINT ESWAR__ID__PK PRIMARY KEY
                                INITIALLY IMMEDIATE
                                NOT DEFERRABLE
                                ENABLE
                                VALIDATE,
  NAME VARCHAR2(10)
       CONSTRAINT ESWAR__NAME__NN NOT NULL
                                INITIALLY IMMEDIATE
                                NOT DEFERRABLE
                                ENABLE
                                VALIDATE
);

db<>fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多