Sql 将特定的日期格式数据限制到表中
我有一个名为Sur_Data的表,数据如下所示:Sql 将特定的日期格式数据限制到表中,sql,sql-server,sql-server-2005,tsql,sql-server-2008,Sql,Sql Server,Sql Server 2005,Tsql,Sql Server 2008,我有一个名为Sur_Data的表,数据如下所示: ID SV_Date 258 13/01/2010 569 15/02/2011 695 26/05/2010 745 12/06/2010 现在,我想从该表中选择ID并插入到另一个表中,因此我们使用类似于: Insert into Surdate(ID) Select ID from Sur_Data where ISDATE(SV_Date) = 1 由于SV_Date中的格式不同,因此不会将任何记录插入S
ID SV_Date
258 13/01/2010
569 15/02/2011
695 26/05/2010
745 12/06/2010
现在,我想从该表中选择ID并插入到另一个表中,因此我们使用类似于:
Insert into Surdate(ID)
Select ID from Sur_Data
where ISDATE(SV_Date) = 1
由于SV_Date中的格式不同,因此不会将任何记录插入Surdate表中
所以我想看看是否有一种方法可以限制Sur_data表中的数据只有MM/DD/YYYY格式的日期。因此,每当他们试图插入不同格式的记录时,都会抛出一个错误
有人能帮忙吗?要严格回答这个问题,您可以创建一个函数(CLR或TSQL)并将其作为列约束/检查应用 但正如@joe Stefanelli正确指出的,将其存储为datetime数据类型,并让客户机处理表示格式 编辑
它假设您定义了一个函数,如果格式符合预期,则返回1。编辑:例如2和3,ANSI警告必须关闭
IS_DATE
函数受当前SQL Server会话/连接的DATEFORMAT
设置的影响
示例1:
DECLARE @d1 VARCHAR(25) = '26/05/2010'
,@d2 VARCHAR(25) = '15/02/2011';
PRINT '*****Test 1*****'
SET DATEFORMAT DMY;
SELECT ISDATE(@d1), ISDATE(@d2);
PRINT '*****Test 2*****'
SET DATEFORMAT MDY;
SELECT ISDATE(@d1), ISDATE(@d2);
SET ANSI_WARNINGS OFF;
SET ARITHABORT OFF;
DECLARE @Results TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
);
INSERT @Results
VALUES
(258, '13/01/2010')
,(569, '15/02/2011')
,(695, '26/05/2010')
,(745, '12/06/2010');
SELECT *
,ISDATE(r.SV_Date) [IS_DATETIME]
,CONVERT(DATETIME,r.SV_Date,103) [IS_DATETIME British/French style=dd/mm/yyyy]
,CONVERT(DATETIME,r.SV_Date,101) [IS_DATETIME U.S. style=mm/dd/yyyy]
,CASE
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_DMY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_DMY_OR_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_NOT_DMY_OR_MDY'
END
FROM @Results r;
DECLARE @Results2 TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
,CHECK( CONVERT(DATETIME,SV_Date,101) IS NOT NULL )
);
SET ANSI_WARNINGS OFF;
INSERT @Results2
VALUES (258, '13/01/2010');
INSERT @Results2
VALUES (569, '15/02/2011');
INSERT @Results2
VALUES (695, '26/05/2010');
INSERT @Results2
VALUES (745, '12/06/2010');
SELECT *
FROM @Results2;
结果:
*****Test 1*****
----------- -----------
1 1
(1 row(s) affected)
*****Test 2*****
----------- -----------
0 0
(1 row(s) affected)
ID SV_Date IS_DATETIME IS_DATETIME British/French style=dd/mm/yyyy IS_DATETIME U.S. style=mm/dd/yyyy
----------- -------------------- ----------- ------------------------------------------- --------------------------------- -----------------
258 13/01/2010 0 2010-01-13 00:00:00.000 NULL IS_DMY
569 15/02/2011 0 2011-02-15 00:00:00.000 NULL IS_DMY
695 26/05/2010 0 2010-05-26 00:00:00.000 NULL IS_DMY
745 12/06/2010 1 2010-06-12 00:00:00.000 2010-12-06 00:00:00.000 IS_DMY_OR_MDY
ID SV_Date
----------- --------------------
745 12/06/2010
(1 row(s) affected)
现在,您可以看到DATEFORMAT
如何影响ISDATE
函数。
您可以使用具有不同属性的CONVERT
函数,而不是ISDATE
函数。如果[n][var]char
值没有选定的样式,则CONVERT
函数将返回NULL。对于dd/mm/yyyy
值(英国)可以使用样式103,对于mm/dd/yyyy
值(美国)可以使用样式101
示例2:
DECLARE @d1 VARCHAR(25) = '26/05/2010'
,@d2 VARCHAR(25) = '15/02/2011';
PRINT '*****Test 1*****'
SET DATEFORMAT DMY;
SELECT ISDATE(@d1), ISDATE(@d2);
PRINT '*****Test 2*****'
SET DATEFORMAT MDY;
SELECT ISDATE(@d1), ISDATE(@d2);
SET ANSI_WARNINGS OFF;
SET ARITHABORT OFF;
DECLARE @Results TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
);
INSERT @Results
VALUES
(258, '13/01/2010')
,(569, '15/02/2011')
,(695, '26/05/2010')
,(745, '12/06/2010');
SELECT *
,ISDATE(r.SV_Date) [IS_DATETIME]
,CONVERT(DATETIME,r.SV_Date,103) [IS_DATETIME British/French style=dd/mm/yyyy]
,CONVERT(DATETIME,r.SV_Date,101) [IS_DATETIME U.S. style=mm/dd/yyyy]
,CASE
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_DMY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_DMY_OR_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_NOT_DMY_OR_MDY'
END
FROM @Results r;
DECLARE @Results2 TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
,CHECK( CONVERT(DATETIME,SV_Date,101) IS NOT NULL )
);
SET ANSI_WARNINGS OFF;
INSERT @Results2
VALUES (258, '13/01/2010');
INSERT @Results2
VALUES (569, '15/02/2011');
INSERT @Results2
VALUES (695, '26/05/2010');
INSERT @Results2
VALUES (745, '12/06/2010');
SELECT *
FROM @Results2;
结果:
*****Test 1*****
----------- -----------
1 1
(1 row(s) affected)
*****Test 2*****
----------- -----------
0 0
(1 row(s) affected)
ID SV_Date IS_DATETIME IS_DATETIME British/French style=dd/mm/yyyy IS_DATETIME U.S. style=mm/dd/yyyy
----------- -------------------- ----------- ------------------------------------------- --------------------------------- -----------------
258 13/01/2010 0 2010-01-13 00:00:00.000 NULL IS_DMY
569 15/02/2011 0 2011-02-15 00:00:00.000 NULL IS_DMY
695 26/05/2010 0 2010-05-26 00:00:00.000 NULL IS_DMY
745 12/06/2010 1 2010-06-12 00:00:00.000 2010-12-06 00:00:00.000 IS_DMY_OR_MDY
ID SV_Date
----------- --------------------
745 12/06/2010
(1 row(s) affected)
现在,如果要检查mm/dd/yyyy
格式(样式101-美国)的SV_日期值,则可以使用如下约束:
示例3:
DECLARE @d1 VARCHAR(25) = '26/05/2010'
,@d2 VARCHAR(25) = '15/02/2011';
PRINT '*****Test 1*****'
SET DATEFORMAT DMY;
SELECT ISDATE(@d1), ISDATE(@d2);
PRINT '*****Test 2*****'
SET DATEFORMAT MDY;
SELECT ISDATE(@d1), ISDATE(@d2);
SET ANSI_WARNINGS OFF;
SET ARITHABORT OFF;
DECLARE @Results TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
);
INSERT @Results
VALUES
(258, '13/01/2010')
,(569, '15/02/2011')
,(695, '26/05/2010')
,(745, '12/06/2010');
SELECT *
,ISDATE(r.SV_Date) [IS_DATETIME]
,CONVERT(DATETIME,r.SV_Date,103) [IS_DATETIME British/French style=dd/mm/yyyy]
,CONVERT(DATETIME,r.SV_Date,101) [IS_DATETIME U.S. style=mm/dd/yyyy]
,CASE
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_DMY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NOT NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NOT NULL THEN 'IS_DMY_OR_MDY'
WHEN CONVERT(DATETIME,r.SV_Date,103) IS NULL AND CONVERT(DATETIME,r.SV_Date,101) IS NULL THEN 'IS_NOT_DMY_OR_MDY'
END
FROM @Results r;
DECLARE @Results2 TABLE
(
ID INT PRIMARY KEY
,SV_Date VARCHAR(20) NOT NULL
,CHECK( CONVERT(DATETIME,SV_Date,101) IS NOT NULL )
);
SET ANSI_WARNINGS OFF;
INSERT @Results2
VALUES (258, '13/01/2010');
INSERT @Results2
VALUES (569, '15/02/2011');
INSERT @Results2
VALUES (695, '26/05/2010');
INSERT @Results2
VALUES (745, '12/06/2010');
SELECT *
FROM @Results2;
结果:
*****Test 1*****
----------- -----------
1 1
(1 row(s) affected)
*****Test 2*****
----------- -----------
0 0
(1 row(s) affected)
ID SV_Date IS_DATETIME IS_DATETIME British/French style=dd/mm/yyyy IS_DATETIME U.S. style=mm/dd/yyyy
----------- -------------------- ----------- ------------------------------------------- --------------------------------- -----------------
258 13/01/2010 0 2010-01-13 00:00:00.000 NULL IS_DMY
569 15/02/2011 0 2011-02-15 00:00:00.000 NULL IS_DMY
695 26/05/2010 0 2010-05-26 00:00:00.000 NULL IS_DMY
745 12/06/2010 1 2010-06-12 00:00:00.000 2010-12-06 00:00:00.000 IS_DMY_OR_MDY
ID SV_Date
----------- --------------------
745 12/06/2010
(1 row(s) affected)
意见:
如果要查找当前DATEFORMAT
设置(当前会话),则可以使用:
为什么不为
SV_Date
列使用适当的(或2008年)数据类型?@JoeStefanelli I I am,但也将插入2010年5月26日、2011年2月15日等日期,但当我使用isdate()时在这些表上,它将返回0,并且不会插入到另一个表中。在插入/更新之前,在表上设置一个触发器,将日期转换为所需的格式如何?@Peter-datetime列不会有“格式”。我想你有些困惑。如果您的列给您的内容表明它不是日期,那么您就没有使用datetime列数据类型。@Peter:adatetime
列是一个datetime
列是一个datetime
列-它没有任何“格式”或任何概念-它只是一个值。仅当在SQL Server Mgmt Studio或您的应用程序中显示此类数据时,格式才会起作用。有关更多详细信息,请参阅扫描您告诉我如何应用约束/检查?更新了示例和链接以更改表语法+1巧妙地使用转换函数和datetime。我从来没有意识到它有这个功能。@Bogdan当我执行它们时,我得到了一些错误,比如:Msg 242,级别16,状态3,第7行。将varchar数据类型转换为datetime数据类型会导致值超出范围。声明已终止。您测试了什么?您是否更改了数据类型?@Bogdan我对上述评论感到抱歉。但这正是我要找的。非常感谢你。谢谢你在这方面的帮助。@Peter:告诉我你举了什么例子?示例1/2/3?