将特定日期格式数据限制为表格

时间:2011-09-21 18:12:54

标签: 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中的格式不同,因此不会将任何记录插入Surdate表。

所以我试图看看有没有办法可以将Sur_Data表中的数据限制为只有MM / DD / YYYY格式的日期。所以当他们尝试插入不同格式的记录时,它应该抛出一个错误。

有人可以为此提供帮助吗?

2 个答案:

答案 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 stylesISDATE函数代替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