web-dev-qa-db-ja.com

SQL Serverの日時形式について

私は長い間MS SQL Serverの日時型を扱ってきましたが、次のことが起こっている理由を考えたことはありません。

  1. Smalldatetime列を含むテーブルをクエリします。このsmalldatetimeは常にyyyy-MM-dd hh:mm:ssの形式で返されます
  2. 次に、WHERE TimeStamp >= 'yyyy-MM-dd hh:mm:ss'のような、WHERE句でsmalldatetimeフィルターを適用する別のクエリを作成します。
  3. SQL Serverがエラーを取得し、そのnvarcharを有効なsmalldatetimeに変換できなかったことを通知します

指定したフォーマットを変更し、WHERE TimeStamp >= 'dd-MM-yyyy hh:mm:ss'のようなヨーロッパのフォーマットを使用して記述した場合にのみ機能するようです。 SQL Serverが日付を自分自身に適用した場合、日付をカバーできないか有効ではない形式で表示するのはなぜですか?クエリを作成するときに日付形式を変更しても問題はありませんが、アプリケーションレベル(Java-JDBCアプリ)でこれらの日付を操作し、常に日付形式の変更を適用したくありません。 ..なぜこれが起こっているのか、そしてDBレベルでそれを解決する方法があるかどうか誰かが私に説明できますか?ありがとう!!

編集:以下のManagement Studioのエラーのスクリーンショットをご覧ください。 enter image description here

2
Hauri

SQL ServerでのDATETIME/SMALLDATETIMEの本当に安全な形式は次のとおりです。

_yyyyMMdd
yyyyMMdd hh:nn:ss[.mmmmmmm]
yyyy-MM-ddThh:nn:ss[.mmmmmmm]
----------^ yes, that T is important!
_

それ以外のものは、SQL Server、Windows、プロバイダー、アプリケーションコード、エンドユーザーなどによる誤った解釈の影響を受けます。たとえば、次の場合は常に壊れます。*

_SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '2013-11-13');
_

結果:

Leparamètrede langue estpasséàFrançais。
メッセージ242、レベル16、状態3、行2
La Conversion d'un type dedonnéesvarchar en type dedonnéesdatetimecrééune valeur hors limites。

言語を変更するだけで(ユーザーセッションで実行できる)、SQL Serverは_YYYY-DD-MM_ではなく_YYYY-MM-DD_として解釈するように強制されました。 DATEFORMATのような設定でも同様のことが起こります。ただし、上記の2つの形式を使用する場合、これらの設定は文字通り無視されます。

常に、常に、常に上記の2つの形式のいずれかを使用してください。変数を文字列として渡す場合は、それをやめます。できない場合は、最初にISDATE()を渡すことを確認してください。フォームフィールドに日付文字列を入力させる場合は、それもやめます。日付ピッカーまたはカレンダーコントロールを使用し、SQL Serverに渡す前に文字列の形式を指示します。まあ、言語によっては、それを日時値として保持し、それを文字列に変換しないでください。

私はあなたの問題をまったく再現できません、ところで ...

この投稿を読んでください:

悪いキックの習慣:日付/範囲のクエリの取り扱いが不適切

例外があります:SELECT CONVERT(DATE, 'yyyy-mm-dd');は壊れません。しかし、私は一貫性の面で誤りを犯します。フォーマットが壊れないことがわかっている1つの場所でのみフォーマットを使用し、他の場所ではより安全なフォーマットを使用する必要があるのではありません。

12
Aaron Bertrand

SQL Server Books Online Write International Transact-SQL Statements によると、次のように日付文字列をラップできます。

{ ts 'yyyy-mm-dd hh:mm:ss[.fff] '}

例:

{ ts '1998-09-24 10:02:20' }

Tを途中に挿入する代わりに、文字列を最初と最後に連結するだけなので、これは簡単に実現できます。

注意点:この構文を使用する場合、正確な型を制御することはできません。結果は常にdatetimeです。 (質問のように)smalldatetime結果を得るには、変換(またはキャスト)を使用する必要があります。その場合は、最初に(正しいスタイルパラメータを使用して)convertだけを使用することもできます。

5
ErikE