Sql条件不空约束

时间:2012-04-23 01:25:04

标签: sql constraints notnull


我很想知道是否有可能在sql中创建一个条件非空约束?换句话说,可以创建一个约束,使得列B可以为空,因为列A包含让我们说“新”,但如果列A的内容更改为其他内容,则不再允许列B为空?
并且为了扩展它,那么只要列A表示“新”,就可以使列B必须为空或空? 谢谢大家:D

4 个答案:

答案 0 :(得分:28)

这对于CONSTRAINT CHECK来说非常好。就这样做:

要求:

  

是否可以创建约束,使列B可以为空   因为列A包含让我们说'新'但是如果列的内容   不再允许更改其他内容,然后更改B列   空?

请注意短语:B列可以为空

解决方案:

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      A = 'NEW' -- B can be null or not null: no need to add AND here
      OR (A <> 'NEW' AND B IS NOT NULL)
    )
);

您可以进一步简化:

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      A = 'NEW' 
      OR B IS NOT NULL
    )
);

要求与上述要求互不兼容:

  

为了扩展,可以使它成为B列   只要列A表示“新”,就必须为空或空?

请注意短语:B列必须为空

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      (A = 'NEW' AND B IS NULL)
      OR A <> 'NEW'
    )
);

可以简化这个,更简单,但可能不像上面那样可读:

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      A <> 'NEW'
      OR B IS NULL
    )
);

答案 1 :(得分:1)

编辑:如其他答案所述,CHECK是最好的方法,而不是我最初建议的触发器。原文如下:


正如dbaseman建议的那样,触发器是要走的路(不是这样)。尝试这样的事情(未经测试):

CREATE OR REPLACE TRIGGER test
  BEFORE UPDATE ON table1
FOR EACH ROW
WHEN (new.A = 'NEW' and new.B IS NOT NULL)
   RAISE_APPLICATION_ERROR (
     num=> -20001,
     msg=> 'B must be NULL for new rows (A = NEW)'
);

答案 2 :(得分:1)

我认为你的第一个要求是:

IF ( B IS NULL ) THEN ( A = 'NEW' )

应用隐含重写规则:

IF ( X ) THEN ( Y )   <=>   ( NOT ( X ) OR ( Y ) )

在你的情况下;

( NOT ( B IS NULL ) OR ( A = 'NEW' ) )

轻微重写以利用SQL语法:

( B IS NOT NULL OR A = 'NEW' )

您的第二个声明(“延伸”)要求:

IF ( A = 'NEW' ) THEN ( B IS NULL )

应用重写规则:

( NOT ( A = 'NEW' ) OR ( B IS NULL ) )

轻微重写:

( A <> 'NEW' OR B IS NULL )

答案 3 :(得分:0)

Per onedaywhen ,这个答案是犯罪错误,令人憎恶。您可以使用 CHECK 约束。 http://msdn.microsoft.com/en-us/library/ms188258.aspx

没有办法制作条件约束。但是,您应该能够使用触发器完成工作。这就是他们的目的。

http://msdn.microsoft.com/en-us/library/ms189799.aspx

CREATE TRIGGER MyTable.ConditionalNullConstraint ON MyTable.ColumnB
AFTER INSERT
AS
IF EXISTS (SELECT *
    FROM inserted
    WHERE A <> 'NEW' AND B IS NULL
    )
BEGIN
    RAISERROR ('if A is ''NEW'' then B cannot be NULL', 16, 1);
    ROLLBACK TRANSACTION;
END;
GO

请注意,在查询中,您需要引用 inserted ,这是一个行为类似于表的特殊对象,并允许您引用导致触发的行。

当然,在这个例子中,您还需要处理 AFTER UPDATE 来强制执行约束,但这是一般的想法。

相关问题