选择检查约束

时间:2013-03-26 23:19:40

标签: sql-server-2008 check-constraints

我想为我的表创建一个检查约束,如果新的预订范围(start_date,end_date)与已提交的行相交,则无法添加新行。 但我不能在查询约束中放置查询。你知道怎么做吗?

表格:

APARTMAN

        id INT
        price INT

BOOKINGS

        id INT
        start_date DATE
        end_date DATE
        apartman_id INT

[apartman_id] IN (SELECT [id]  FROM [dbo].[APARTMAN]
    WHERE [id]  NOT IN (
        SELECT [apartman_id]    FROM
            [dbo].[BOOKINGS]
        WHERE
            ([start_date] <= "requested end_date" AND
            [end_date] >= "requested start_date" )
            OR
            ([start_date] <= "requested start_date" AND
             [end_date] >= "requested end_date" )
            OR
            (([start_date] <= "requested end_date" AND  [end_date] >= "requested start_date" )
                OR
                ([end_date] <= "requested start_date"  AND  [end_date] >= "requested end_date" ))
    )
)  

1 个答案:

答案 0 :(得分:2)

这是一个而不是我认为处理所有场景的触发器。

CREATE TRIGGER dbo.PreventOverlappingBookings
ON dbo.BOOKINGS INSTEAD OF INSERT, UPDATE
AS
BEGIN
  SET NOCOUNT ON;

  IF EXISTS (
    SELECT 1 FROM inserted AS i
      INNER JOIN dbo.BOOKINGS AS b
      ON (b.id <> i.id OR i.id = 0) -- 0 for insert
      AND b.apartman_id = i.apartman_id
      AND ((b.start_date   <= i.end_date   AND b.end_date >= i.start_date)
         OR (b.start_date  <= i.start_date AND b.end_date >= i.end_date)
         OR (b.end_date    <= i.start_date AND b.end_date >= i.end_date))
  ) OR EXISTS (
    -- also make sure there are no overlaps in a set-based insert/update
    SELECT 1 FROM inserted AS i
      INNER JOIN inserted AS b
      ON (b.id <> i.id OR i.id = 0) -- 0 for insert
      AND b.apartman_id = i.apartman_id
      AND ((b.start_date   <= i.end_date   AND b.end_date >= i.start_date)
         OR (b.start_date  <= i.start_date AND b.end_date >= i.end_date)
         OR (b.end_date    <= i.start_date AND b.end_date >= i.end_date))
  )
  BEGIN
    RAISERROR('Overlapping date range.', 11, 1);
  END
  ELSE
  BEGIN
      UPDATE b SET start_date = i.start_date, end_date = i.end_date
        FROM dbo.BOOKINGS AS b
        INNER JOIN inserted AS i
        ON b.id = i.id;
      IF @@ROWCOUNT > 0
      BEGIN
        INSERT dbo.BOOKINGS(start_date, end_date, apartman_id)
          SELECT start_date, end_date, apartman_id FROM inserted AS i;
      END
  END
END
GO

一些答案​​will suggest a function in a UDF,但I don't trust them (and neither should you, IMHO)