我有一个名为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中的格式不同,因此不会将任何记录插入Surdate表。
所以我试图看看有没有办法可以将Sur_Data表中的数据限制为只有MM / DD / YYYY格式的日期。所以当他们尝试插入不同格式的记录时,它应该抛出一个错误。
有人可以为此提供帮助吗?
答案 0 :(得分:1)
要严格回答这个问题,您可以创建一个函数(CLR或TSQL)并将其应用为列约束/检查。
但正如@joe Stefanelli正确指出的那样,将其存储为日期时间数据类型并让客户端处理表示格式。
http://msdn.microsoft.com/en-us/library/ms190273.aspx
ALTER TABLE
dbo.Sur_Data
WITH CHECK
ADD CONSTRAINT ck_dateFormatted CHECK (dbo.VerifyDateFormat(SV_Date) = 1) ;
假设您定义了一个函数,如果格式符合期望值,则返回1。
答案 1 :(得分: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);
结果:
*****Test 1*****
----------- -----------
1 1
(1 row(s) affected)
*****Test 2*****
----------- -----------
0 0
(1 row(s) affected)
现在,您可以看到DATEFORMAT
如何影响ISDATE
功能。
您可以使用不同date/time styles的ISDATE
函数代替CONVERT
函数。如果[n][var]char
值没有所选样式,则CONVERT
函数将返回NULL。对于dd/mm/yyyy
值(英国),可以使用样式103,对于mm/dd/yyyy
值(美国)可以使用样式101.
示例2:
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;
结果:
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
现在,如果您想检查mm/dd/yyyy
格式的SV_Date值(样式101 - 美国),那么您可以使用CHECK
这样的约束:
示例3:
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;
结果:
ID SV_Date
----------- --------------------
745 12/06/2010
(1 row(s) affected)
观察:
如果您想查找当前DATEFORMAT
设置(当前会话),则可以使用sys.dm_exec_sessions
view:
SELECT s.date_format, s.date_first
FROM sys.dm_exec_sessions s
WHERE s.session_id = @@SPID