SQL 约束:特定键每天只能有一条记录

发布于 2025-01-08 14:25:46 字数 465 浏览 3 评论 0原文

有没有一种方法可以创建约束或某种方式,让 FK 列一天只能有一条记录? IE

PK(IDENTITY(1,1))  FK_FIELD DATETIME
------------------------------
1                  1        2012-02-22 4:50 p.m.
2                  2        2012-02-23 12:00 p.m.
3                  2        2012-02-23 9:00 p.m.  -- This one should not be allowed because the FK_Field 2 would have 2 record in one day.
4                  1        2012-02-23 08:00 a.m 

希望有人理解我想要实现的目标。

提前致谢。

There is a way to create a constraint or something where I can have only one record for a Day for a FK column? I.E.

PK(IDENTITY(1,1))  FK_FIELD DATETIME
------------------------------
1                  1        2012-02-22 4:50 p.m.
2                  2        2012-02-23 12:00 p.m.
3                  2        2012-02-23 9:00 p.m.  -- This one should not be allowed because the FK_Field 2 would have 2 record in one day.
4                  1        2012-02-23 08:00 a.m 

Hopefully someone understand what im trying to archieve.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

神也荒唐 2025-01-15 14:25:46

考虑使用:

  • 1 个或多个持久计算列
  • 对持久计算列的唯一约束

各种持久列的一些示例(非常感谢 Aaron Bertrand):

  • Y AS YEAR(SOMEDATE) PERSISTED
  • M AS MONTH(SOMEDATE) ) 坚持
  • D 个月(SOMEDATE) 坚持
  • YMD AS 年(SOMEDATE) * 10000 + MONTH(SOMEDATE) * 100 + DAY(SOMEDATE) 持久化
  • SOMEDATEDIFF AS DATEDIFF(DAY, 0, SOMEDATE) 持久化
  • SOMEDATESMALL AS DATEADD(DAY, 0, DATEDIFF(DAY, 0, SOMEDATE)) 持久化
  • SOMEDATESMALL AS CONVERT(DATETIME, FLOOR(CONVERT) (漂浮, SOMEDATE, 105)), 105) PERSISTED
  • SOMEDATESMALL AS CONVERT(DATE, SOMEDATE) PERSISTED -- 需要 SQL Server

2008这些例子是经过仔细选择的,以确保功能确定性。

下面是一个 SQL 示例:

CREATE TABLE DATA
(
     ID INT NOT NULL IDENTITY,
     FK_FIELD INT NOT NULL,
     SOMEDATE DATETIME NOT NULL,
     SOMEDATESMALL AS DATEADD(DAY, 0, DATEDIFF(DAY, 0, SOMEDATE)) PERSISTED,
     CONSTRAINT PK_DATA PRIMARY KEY (ID),
     CONSTRAINT UQ_DATA_SOMEDATESMALL UNIQUE (FK_FIELD, SOMEDATESMALL)
);

如果您尝试插入,您将得到以下结果:

INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (1, '2012-02-22 4:50PM'); -- SUCCESS
INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (2, '2012-02-23 12:00PM'); -- SUCCESS
INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (2, '2012-02-23 9:00PM'); -- CAUGHT
INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (1, '2012-02-23 8:00AM'); -- SUCCESS

SQL Server Management Studio 中显示的消息是:

消息 2627,级别 14,状态 1,第 3 行
违反 UNIQUE KEY 约束“UQ_DATA_SOMEDATESMALL”。
无法在对象“dbo.DATA”中插入重复的键。
该声明已终止。

Consider using:

  • 1 or many persisted computed column(s)
  • Unique constraint on the persisted computed column(s)

Some examples of a variety of persisted columns (Much thanks to Aaron Bertrand):

  • Y AS YEAR(SOMEDATE) PERSISTED
  • M AS MONTH(SOMEDATE) PERSISTED
  • D AS MONTH(SOMEDATE) PERSISTED
  • YMD AS YEAR(SOMEDATE) * 10000 + MONTH(SOMEDATE) * 100 + DAY(SOMEDATE) PERSISTED
  • SOMEDATEDIFF AS DATEDIFF(DAY, 0, SOMEDATE) PERSISTED
  • SOMEDATESMALL AS DATEADD(DAY, 0, DATEDIFF(DAY, 0, SOMEDATE)) PERSISTED
  • SOMEDATESMALL AS CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, SOMEDATE, 105)), 105) PERSISTED
  • SOMEDATESMALL AS CONVERT(DATE, SOMEDATE) PERSISTED -- Requires SQL Server 2008

N.B. These examples were chosen carefully to ensure function determinism.

Here's a sample SQL:

CREATE TABLE DATA
(
     ID INT NOT NULL IDENTITY,
     FK_FIELD INT NOT NULL,
     SOMEDATE DATETIME NOT NULL,
     SOMEDATESMALL AS DATEADD(DAY, 0, DATEDIFF(DAY, 0, SOMEDATE)) PERSISTED,
     CONSTRAINT PK_DATA PRIMARY KEY (ID),
     CONSTRAINT UQ_DATA_SOMEDATESMALL UNIQUE (FK_FIELD, SOMEDATESMALL)
);

If you attempted the INSERTs, this is what you get:

INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (1, '2012-02-22 4:50PM'); -- SUCCESS
INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (2, '2012-02-23 12:00PM'); -- SUCCESS
INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (2, '2012-02-23 9:00PM'); -- CAUGHT
INSERT INTO DATA (FK_FIELD, SOMEDATE) VALUES (1, '2012-02-23 8:00AM'); -- SUCCESS

The message shown in SQL Server Management Studio is:

Msg 2627, Level 14, State 1, Line 3
Violation of UNIQUE KEY constraint 'UQ_DATA_SOMEDATESMALL'.
Cannot insert duplicate key in object 'dbo.DATA'.
The statement has been terminated.

初见 2025-01-15 14:25:46

您可以创建一个检查约束,该约束使用用户定义的函数来检查整个表中是否存在今天的条目。

CREATE TABLE #demo (
    some_date_field DATETIME NULL 
        CHECK (dbo.check_only_one(GETDATE())
)

you can create a check constraint that uses a user defined function that checks the whole table for an existence of a todays entry.

CREATE TABLE #demo (
    some_date_field DATETIME NULL 
        CHECK (dbo.check_only_one(GETDATE())
)
动次打次papapa 2025-01-15 14:25:46

这是一种方法

create table t1 (pk int identity(1,1),fk_field int,theDate DateTime,
                 theDay as convert(varchar(12),theDate,102))
create unique index noDupes on t1 (fk_field,theDay)

您还可以使用约束,正如亚伦建议的那样

create table t1 (pk int identity(1,1),fk_field int,theDate DateTime,
                     theDay as convert(varchar(12),theDate,102)
    CONSTRAINT [noDupes] UNIQUE  ( [fk_field], [theDay])        )               
  • 添加一个仅保存日期的日期部分的计算列。
  • 然后在键和计算字段上创建唯一索引

    插入 t1 值 (1,getDate())        
    插入 t1 值 (2,getDate())          
    插入 t1 值 (2,getDate()) -- 错误    
    插入 t1 值 (3,getDate())
    

Here is one approach

create table t1 (pk int identity(1,1),fk_field int,theDate DateTime,
                 theDay as convert(varchar(12),theDate,102))
create unique index noDupes on t1 (fk_field,theDay)

You can also use a constraint, as Aaron suggested

create table t1 (pk int identity(1,1),fk_field int,theDate DateTime,
                     theDay as convert(varchar(12),theDate,102)
    CONSTRAINT [noDupes] UNIQUE  ( [fk_field], [theDay])        )               
  • Add a computed column that holds just the date portion of the date.
  • Then create a unique index on the key and that computed field

    insert into  t1 values (1,getDate())        
    insert into  t1 values (2,getDate())          
    insert into  t1 values (2,getDate())    -- ERROR    
    insert into  t1 values (3,getDate())
    
天涯离梦残月幽梦 2025-01-15 14:25:46

我会尝试在数据库的两个不同字段中或按组合将日期与时间分开。然后我会在日期上添加一个唯一的约束。只要该日期位于您添加约束的列中,以下内容就会阻止对同一日期进行任何输入。

ALTER TABLE XYZ
    ADD CONSTRAINT UNIQUE( the date field name)

还有一个非常有趣的线程,您应该检查这里解决的类似问题 如何仅在日期时间的日期部分创建唯一约束?

希望这有帮助

I would try to separate the date from the time either in 2 different fields of the database or by composition. Then I would add a unique constraint on the date. The following would prevent any entry to be made for a same date as long as only the date is in the collumn you add the constraint to.

ALTER TABLE XYZ
    ADD CONSTRAINT UNIQUE( the date field name)

There is also a quite interesting thread you should check with a similar problem that was solved here How to create a unique constraint just on the date part of a datetime?

Hope this helps

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