Ограничить конкретный формат даты данными в таблице - PullRequest
0 голосов
/ 21 сентября 2011

У меня есть таблица с именем Sur_Data, и данные выглядят следующим образом:

ID     SV_Date
258    13/01/2010
569    15/02/2011
695    26/05/2010
745    12/06/2010

Теперь я хочу выбрать идентификаторы из этой таблицы и вставить в другую таблицу, чтобы мы использовали что-то вроде:

Insert into Surdate(ID)
Select ID from Sur_Data
where ISDATE(SV_Date) = 1

Так как формат в SV_Date отличается, он не вставляет никаких записей в таблицу Surdate.

Поэтому я пытаюсь понять, есть ли способ, которым мы могли бы ограничить данные в таблице Sur_Data толькодаты в формате ММ / ДД / ГГГГ. Поэтому, когда они пытаются вставить записи другого формата, должно выдаваться сообщение об ошибке.

Может кто-нибудь помочь с этим?

Ответы [ 2 ]

1 голос
/ 22 сентября 2011

Редактировать: например 2 и 3, ПРЕДУПРЕЖДЕНИЯ ANSI должны быть выключены.

На функцию

IS_DATE влияет настройка DATEFORMAT для текущего сеанса / соединения SQL Server.

Пример 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. Вместо функции 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

Теперь, если вы хотите проверить значения SV_Date для формата mm/dd/yyyy (стиль 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 
1 голос
/ 21 сентября 2011

Чтобы строго ответить на вопрос, вы можете создать функцию (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, если формат соответствуетожидание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...