SOに関するSQLの質問に答えるのに多くの時間を費やしています。私はこのilkのクエリに頻繁に出くわします:
SELECT * FROM person WHERE birthdate BETWEEN '01/01/2017' AND '01/03/2017'
SELECT * FROM person WHERE birthdate BETWEEN '2017-01-01' AND '2017-03-01'
SELECT * FROM person WHERE birthdate BETWEEN 'some string' AND 'other string'
つまり、指定されたパラメータの文字列から日付への暗黙的な変換(不良)に依存するか、データベースがx、000,000個のデータベース行値を文字列に変換し、文字列比較を実行します(悪い)
私は時々コメントをします。特に、スマートな回答を書くのが高回答ユーザーである場合、私は本当に自分のデータ型でだらしない/文字列を入力するべきではないと思う人
コメントは通常、to_date(Oracle)、str_to_date(MySQL)、convert(SQLSERVER)、または同様のメカニズムを使用して、文字列を明示的に日付に変換した方が良いと思われる形式を取ります。
--oracle
SELECT * FROM person WHERE birthdate BETWEEN TO_DATE('20170101', 'YYYYMMDD') AND TO_DATE('20170301', 'YYYYMMDD')
--mysql
SELECT * FROM person WHERE birthdate BETWEEN STR_TO_DATE('20170101', '%Y%m%d') AND STR_TO_DATE('20170301', '%Y%m%d')
--SQLS, ugh; magic numbers
SELECT * FROM person WHERE birthdate BETWEEN CONVERT(datetime, '20170101', 112) AND CONVERT(datetime, '20170301', 112)
これを行うための技術的な理由は、日付の形式が明示的であり、いくつかのソースパラメーターが確実にターゲット列のデータ型になることです。これにより、データベースが暗黙的な変換を誤ってしまう可能性を防ぎ(最初の例の1月3日/ 1月3日の引数)、dbがテーブル内の100万の日付値を文字列に変換することを決定します(サーバー固有の日付を使用して)比較を行うために、sql内の文字列パラメーターの日付の形式と一致しない可能性があるフォーマット-ホラーがたくさん
そうすることに対する私の社会的/学術的正当性は、SOが学習サイトであるということです。暗黙的または明示的に知識を習得します。このクエリを答えとして初心者をヒットするには:
SELECT * FROM person WHERE birthdate BETWEEN '2017-01-01' AND '2017-03-01'
これは賢明だと思うように彼らを導くかもしれません。
SELECT * FROM person WHERE birthdate BETWEEN '01/01/2017' AND '01/03/2017'
少なくとも日付を変換する明示的な試みを見た場合は、奇妙な日付形式でそれを実行し、発生する前にいくつかの永遠のバグを殺すかもしれません。結局、私たちは、人々がSQLインジェクションの習慣にならないようにしようとしています(そして@pBirthdate
、フロントエンドにdatetime型がある場合、クエリをパラメーター化してから、文字列であるドライバーに宣言することを推奨しますか?)
推奨事項を作成した後に戻る:通常、「明示的に、xを使用」推奨事項へのプッシュバックを取得します。それは私が明示的であるべきだと言っている」あるいは「何?」
これらのいくつかに応えてWHERE age = '99'
、年齢を文字列として渡すことでint列を検索するかどうかを尋ねました。「愚かなことをしないで、「intを検索するとき」を入力する必要はありません。そのため、どこかでさまざまなデータ型を認識しているかもしれません。文字列を渡すことによる(明らかに愚かな)列と文字列を渡すことによる(明らかに賢明な)日付列の検索は偽善的です
したがって、SQLには、数値(区切り記号なしの数値を使用)、文字列文字列(アポストロフィ区切り記号の間にあるものを使用)として物事を書く方法があります。ほとんどのDBでこれは基本的なデータ型ですか?javascript /
がいくつかの文字のどちらかの側を置くことで正規表現を指定できるように、日付を書く方法を持っているだけで、この全体を解決できるかもしれません。/Hello\s+world/
。デート用に何か持ってみませんか?
実際、私の知る限り、Microsoft Accessには「これらの区切り記号の間に日付が書き込まれている」ことを示す記号が実際にあるため、次のような良いショートカットを取得できますWHERE datecolumn = #somedate#
が、日付の表示には問題があります:mm / di vs dd / mm、MSは常にVBの観客が良いアイデアだと思ったもので、速くてゆるいプレイをしてきたからです。
要点に戻ります:多数の異なるデータ型を文字列として渡すことを強制するこの媒体を明示するのが賢明であると主張しています。
有効なアサーションですか?
この十字軍を続けるべきですか?文字列型入力が現代のノーノーであることは有効なポイントですか?または、すべてのRDBMS(古代バージョンを含む)が存在する場合、クエリを実行WHERE datecolumn = 'string value'
すると、文字列が確実に正しく日付に変換され、テーブルデータの変換/インデックスの使用を失うことなく検索が実行されますか?少なくとも、Oracle 9の個人的な経験からは、そうではないと思います。文字列が常にISO標準形式で記述されていて、列が何らかの日付フレーバーである場合、逃げるシナリオがあるかもしれません。文字列パラメーターは常に正しく暗黙的に変換されます。これは正しいですか?
やりがいのある仕事ですか?
多くの人はそれを取得していないようであるか、気にしないか、またはintがintであるにもかかわらず日付が文字列であるという偽善を示します。ほとんどの人に共通しているのは、なに、あなたの意見に同意します。これからの日付について明確にします。」
WHERE age = '0x0F'
。..データベースは、15歳の検索を願っする有効な方法である
WHERE datecolumn =
01/02 / 12'`で問題を抱えているのを見たことがありますが、1912、2012、2001、1901、12または1年を求めている可能性があります。変換理由を理解することはできませんプログラマーの"09"
クラッシュを引き起こしているint型にしている軍団、9が有効進数字ではなく、先頭の0は、多くのシステムでは、文字列進を作る