web-dev-qa-db-ja.com

ANSI日時付きのSQL Serverエラー242

MS SQL Serverエラー242をデバッグしようとしています:

Charデータ型をdatetimeデータ型に変換すると、範囲外のdatetime値が発生しました。

エラーの原因は次のとおりです。

CREATE TABLE db.schema.test (
    Column1 datetime NULL
) GO

INSERT INTO db.schema.test (Column1)
VALUES (convert(varchar,convert(datetime,{D '2019-06-30'}),102));

これは私のサーバーバージョンです:

Microsoft SQL Server 2017 (RTM-CU15) (KB4498951) - 14.0.3162.1 (X64) 
    May 15 2019 19:14:30 
    Copyright (C) 2017 Microsoft Corporation
    Standard Edition (64-bit) on Linux (Debian GNU/Linux 9 (stretch))

そして言語@@LANGUAGEItalianoです。

同じステートメントが機能します

Microsoft SQL Server 2017 (RTM-CU10) (KB4342123) - 14.0.3037.1 (X64)
   Jul 27 2018 09:40:27
   Copyright (C) 2017 Microsoft Corporation
   Standard Edition (64-bit) on Windows Server 2012 R2 Standard 6.3 <X64> (Build 9600: ) (Hypervisor) 

言語:us_english

明示的な変換スタイルを作成せずに機能します

INSERT INTO db.schema.test (Column1)
VALUES (convert(varchar,convert(datetime,{D '2019-06-30'})));

変換スタイル102はANSI yyyy.mm.dd、英語とイタリア語の両方のSQL Serverで認識されるべきではありませんか?

6
sgargel
VALUES (convert(varchar,convert(datetime,{D '2019-06-30'}),102));

内側から、ODBC=エスケープシーケンス{D '2019-06-30'}datetimeを返します。

datetimeへの冗長な変換を無視)

次に、それを(イタリア語の105ではなく)102スタイルの文字列に変換します。

次に、datetimeへの暗黙的な変換を使用して、ターゲット列のタイプと一致させます。

実行プランで確認できるように、暗黙の変換のデフォルトスタイルは0です。

[Expr1003] = Scalar Operator(CONVERT_IMPLICIT(datetime,CONVERT(varchar(30),[@1],102),0))

(注:varcharを使用する場合は、常に最大長を指定する必要があります)

スタイル102 yyyy.mm.ddを使用する場合は、DATEFORMATYMDに設定して、SQL Serverがスタイル0でフォーマットを解析できるようにする必要もあります。

スタイル105 dd-mm-yyyyを使用する場合、同じ理由でDATEFORMATDMYに設定する必要があります。

どちらか一方で機能する理由は、それぞれの言語のデフォルトのDATEFORMATです。

ドキュメントの datetimeSET LANGUAGE 、および International Transact-SQLステートメントの記述 を参照してください。

他のAPI、またはTransact-SQLスクリプト、ストアドプロシージャ、およびトリガーを使用するアプリケーションでは、 [〜#〜] convert [〜#〜] ステートメントを使用して、timedatesmalldatedatetimedatetime2、およびdatetimeoffsetデータ型と文字列データ型。

また SQL Server DateTimeのベストプラクティス Aaron Bertrandによる。

13
Paul White 9