web-dev-qa-db-ja.com

SET DATEFORMATの問題

SET DATEFORMAT コマンドについて疑問があります。

1)このコマンドは日付形式の挿入と更新にのみ使用され、その列の日付形式には影響しませんか? ORこれは値を挿入した後もテーブルに影響しますか?

2)以下のコマンド(日付データ型)を使用しようとすると、This session's YDM date format is not supported when converting from this character string format to date, time, datetime2 or datetimeoffset. Change the session's date format or provide a style to the explicit conversion.のようなエラーが発生しました。日付データ型でエラーが発生する理由(smalldatetimeはリンクに示されているように機能します)?

CREATE TABLE #tempTable (DateFormatSample DATE)
SET DATEFORMAT MDY
INSERT INTO #tempTable
VALUES ('09/28/2007')
SET DATEFORMAT YDM
INSERT INTO #tempTable
VALUES ('2007/28/09')
SET DATEFORMAT YMD
INSERT INTO #tempTable
VALUES ('2007/08/28')
SELECT DateFormatSample
FROM #tempTable
DROP TABLE #tempTable

3)「SET DATEFORMATの設定は実行時または実行時に設定され、解析時ではありません。」のように述べられていました。どういう意味ですか?

3
IT researcher

1)SET DATEFORMATは、テーブルの実際のストレージには影響しません。出力のフォーマットと文字列の解釈にのみ使用されます。舞台裏では、すべての日付形式が標準形式の整数として格納されています。

データ型の実際の表現は、使用される型によって異なります。たとえば、SMALLDATETIMEは1900-01-01からの秒数を格納する整数です。このようにキャストすると、この気泡の一部が表面に出ます。

SELECT CAST(0 AS SMALLDATETIME)

結果:1900-01-01 00:00:00

同様に、DATETIMEの場合:

SELECT CAST(0 AS DATETIME)

結果:1900-01-01 00:00:00.000

興味深いことに、これは失敗します。

SELECT CAST(0 AS DATE)

例外:データ型intから日付への明示的な変換は許可されていません。

明らかなように、新しいタイプでは、何かがかなり具体化されていません。

2)この制限はここに文書化されています: http://msdn.Microsoft.com/en-gb/library/ms189491.aspx

DATEFORMAT ydmは、date、datetime2、およびdatetimeoffsetデータ型ではサポートされていません。

これはなぜですか?データベースエンジンの内部DATEDATETIME2およびDATETIMEOFFSETは、DATETIMEおよびSMALLDATETIMEとは異なるコードパスを使用します(プロファイラーでこれを検証できます)。新しい日付形式はDATETIME/SMALLDATETIME-さまざまなプログラマがそれに取り組んだため、一部の機能は100%調整されていません(まだ)。別の例:SQL Server 2008R2の初期バージョンでは、DATEの一括読み込みはSMALLDATETIMEの一括読み込みよりもはるかに低速でしたが、一方が他方よりも小さくなっていました。これはリリース前に修正されました。これは、多くのコーダーがいる大規模な組織で発生することです。

3)これは、実際に試すまで、日付形式が有効かどうかを知ることができないことを意味します。あなたのケースでは、実行せずに「show query plan」を実行しても、実際にクエリを実行するまで、フォーマットにエラーがあることがわかりません。

6
Thomas Kejser

質問への直接の回答ではありませんが、リンク先のブログ投稿に示された例が本当に良い例であるとは完全には確信していませんSET DATEFORMAT

DATEFORMATを使用する必要がある主な理由の1つは、日付を複数の方法で解釈できる場合です。

国によって日付の形式が異なるグローバルビジネスで働いている場合は、DATEFORMATを使用して、受け取る予定の形式を具体的に設定することが重要です。

私が米国に住んでいて、英国の同僚からファイルをインポートしたとします。以下の例では、インポートされる日付はLANGUAGE設定によって異なります。

CREATE TABLE #tempTable (DateFormatSample DATE, ID INT IDENTITY(1,1));

INSERT INTO #tempTable
VALUES ('08/07/2007');

INSERT INTO #tempTable
VALUES ('07/08/2007');

私の米国の言語設定に基づいて、これは挿入します:

DateFormatSample    ID
2007-08-07           1
2007-07-08           2

ただし、DATEFORMATをUK形式に設定すると...:

CREATE TABLE #tempTable (DateFormatSample DATE, ID INT IDENTITY(1,1));

SET DATEFORMAT DMY;

INSERT INTO #tempTable
VALUES ('08/07/2007');

INSERT INTO #tempTable
VALUES ('07/08/2007');

私は完全に異なる日と月を取得します:

DateFormatSample    ID
2007-07-08           1
2007-08-07           2

日付は有効であるため、クエリはエラーになりませんが、予期しない結果が生じます。毎月、完全な12日間のデータを間違った形式でインポートし、システムを混乱させてしまう可能性があります。

2
Mark Sinkinson