添加简单约束 - 数据库

时间:2017-02-26 18:40:04

标签: sql postgresql

我正在尝试在数据库中添加简单约束。 I follow this

我的目标:在Tenants表中,如果LeaseExpirationDate不是NULL,那么它必须晚于LeaseStartDate。

我试过了:

SELECT
     S2.S#
    ,S2.SName
FROM S
INNER JOIN S S2
    ON S.S# <> S2.S#
    AND S.City = S2.City
WHERE S.SName = 'Jones'
;

然后我尝试:

alter table Tenants
   add constraint leasedates_check check (leaseexpirationdate is not null or leaseexpirationdate > leasestartdate);

即使UPDATE Tenants SET leaseexpirationdate = leasestartdate WHERE apartmentnumber = 1 and houseid = 100; ,行也会更新。我哪里错了?我不是在比较日期吗?

创建声明:

leaseexpirationdate is not null

我正在使用Postgresql。

3 个答案:

答案 0 :(得分:4)

评论太长了。

此约束:

alter table Tenants
   add constraint leasedates_check check (leaseexpirationdate is not null or leaseexpirationdate > leasestartdate);

相当于:

alter table Tenants
   add constraint leasedates_check check (leaseexpirationdate is not null);

据推测,你似乎打算:

  add constraint leasedates_check check (leaseexpirationdate is null or leaseexpirationdate > leasestartdate);

请注意,该检查适用于is nullor是连接器。

答案 1 :(得分:3)

  

我的目标:在租户表中,如果LeaseExpirationDate不是NULL,那么它必须晚于LeaseStartDate。

     

check(leaseexpirationdate is not null or leaseexpirationdate > leasestartdate)

这表示leaseexpirationdate不能为空, 或如果为空 ,则必须大于leasestartdate。比较null并不是非常有用。它将返回unknown,这是SQL's ternary logic中的第三个布尔值。

相反,您要检查leaseexpirationdate是否为空 ,或者如果它不是 ,则必须大于leasestartdate

check(leaseexpirationdate is null or leaseexpirationdate > leasestartdate)

答案 2 :(得分:0)

Postgresql对日期时间类型有一个特殊的infinity value,可以表达这些规则 saner 。在这里,如果我没有弄错的话,空值用于表示没有到期日的租约。

  

我的目标:在Tenants表中,如果LeaseExpirationDate不为NULL,则它必须晚于LeaseStartDate。

因此,表定义可以是:

CREATE TABLE "Tenants"(
  "HouseID" INT NOT NULL,
  "ApartmentNumber" INT NOT NULL,
  "LeaseTenantSSN" INT NOT NULL,
  "LeaseStartDate" DATE NOT NULL,
  "LeaseExpirationDate" DATE NOT NULL DEFAULT 'INFINITY',
  "Rent" DECIMAL(7,2),
  "LastRentPaidDate" DATE,
  "RentOverdue" BOOLEAN,

  PRIMARY KEY("HouseID", "ApartmentNumber")
);

并且,检查约束可以是:

ALTER TABLE "Tenants"
   ADD CONSTRAINT leasedates_check check ("LeaseExpirationDate" > "LeaseStartDate");

@Gordon Linoff上面的回答也是正确的,并且是大多数开发人员处理开始/结束时间的默认方式。数据库中的相关约束。

另请注意,Postgresql标识符不区分大小写,除非引用,如本答案所示。