5

誰かがMicrosoftConnectでこのバグを報告しました:

Microsoft ConnectionのWebサイトで、次のバグレポートに遭遇しました。ユーザーは、関数が2012を含む期間IsDate (Transact-SQL)の形式の期間を検証していたが、 2013年の初めから機能を停止したと報告しました。YYYYMM

ISDate()は、2013年以降に異なる結果を返します

入力データとして以下のことが報告されています。ユーザーが期待しているものとSQLServerからの出力をリストしました。

SELECT  ISDATE(201201)      AS CheckDate1   --Expected: 1; Actual: 1
    ,   ISDATE(201301)      AS CheckDate2   --Expected: 1; Actual: 0
    ,   ISDATE(201401)      AS CheckDate3   --Expected: 1; Actual: 0
    ,   ISDATE(20130101)    AS CheckDate4   --Expected: 1; Actual: 1

MSDNのドキュメントを読んでください。

についてのMSDNWebサイトのドキュメントを読みましたISDATE (Transact-SQL)YYYYMMドキュメントには以下の定義が記載されていますが、関数によって検証されていることを確認する例は見つかりませんでした。

Returns 1 if the expression is a valid date, time, or datetime value; 
otherwise, 0.

データ型datetime(Transact-SQL)に関する定義YYYYMMでは、有効な日付形式であることを示唆するものは見つかりませんでした。ユーザーが指定した値もdatetime2形式ではありません。

何が起こっているのかを知るために、以下のスクリプトを書きました。

クエリは、何が起こっているのかを調べようとします。

DECLARE @StartAt    INT;
DECLARE @EndAt      INT;

SET @StartAt    = 200000;
SET @EndAt      = 201312;

;WITH Numbers AS 
(
    SELECT @StartAt AS n
    UNION ALL
    SELECT n + 1 FROM Numbers WHERE n < @EndAt
)
SELECT  n           AS Number
    ,   ISDATE(n)   AS IsValidDate 
FROM    Numbers 
WHERE   ISDATE(n) <> 0
OPTION (MAXRECURSION 10000);

上記のクエリ結果:

上記のクエリは、 2012年の各日に366行を返しました。これは2月から3月までのデータのスナップショットです。値200229はIsDateによって有効と見なされますが、200230では有効とは見なされません。これにより、IsDateはこれらの形式の値を処理しており、ユーザーが期待していたようには処理していないと思います。YYMMDDYYYYMM

Number  IsValidDate
------  -----------
200227        1
200228        1
200229        1
200301        1
200302        1
200303        1

質問:

  • IsDateが上記の値をYYMMDDではなくとして扱っているのは正しいYYYYMMですか?

  • 関数YYMMDDが実際に評価しようとしている形式である場合、それはどの世紀を表しますか。1920それは年の値または2020何か他のものを表していますか?それとも関係ありませんか?

  • 上記のクエリの開始値と終了値を以下の値に置き換えました。また、これらの範囲の間に見つかった有効な行の数もリストしました。00から09で終わる年が行を返さないのはなぜですか?

複数回の試行:

Start   End     Rows
------  ------  ----
000000  001231     0
010000  011231     0
020000  021231     0
030000  031231     0
040000  041231     0
050000  051231     0
060000  061231     0
070000  071231     0
080000  081231     0
090000  091231     0
100000  101231   365
110000  111231   365
120000  121231   366
...
...
980000  981231   365
990000  991231   365

上記のクエリを実行するために使用したSQLServerのバージョン:

上記のクエリをバージョンで実行しました。ユーザーがMicrosoftConnectWebサイトのそのバージョンでこの問題を報告したため、この質問に

Microsoft SQL Server 2012 - 11.0.2316.0 (X64) 
Apr  6 2012 03:20:55 
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> 
(Build 7601: Service Pack 1) (Hypervisor)
4

3 に答える 3

2

isdateが行うのは、文字列を日付に変換できるかどうかを確認することだけです。

彼らは12が有効な月であるというだけで幸運でした

例としてこれを実行します

SELECT ISDATE('201201'),ISDATE('201301'),ISDATE('199901')

ご覧のとおり、1999も0を返します

そしてもちろん、あなたはこのようなものを楽しむことができます

SELECT ISDATE(CONVERT(DATETIME,0)),ISDATE(CONVERT(DATETIME,''))
于 2013-02-14T21:34:41.217 に答える
2
  1. ISDATEは、6文字の文字列を。として解釈していyymmddます。

  2. これは、構成されたカットオフサーバー構成オプションに依存します。デフォルトは、であるため、 *で2049終わる年はであり、年はです。< 5020xx>= 5019xx

  3. テストコードは整数を処理してisdateおり、先行ゼロなしで引数として渡されると、暗黙的に文字列にキャストされます。

于 2013-02-14T21:56:26.187 に答える
1

あなたの結果に基づいて、例えば201201また201301ははとして解釈されるように思われるでしょうYYMMDD。(そして、13か月目の日付は無効と見なされます。)

于 2013-02-14T21:35:36.220 に答える