正しいアプローチ
を無視する しばらくの間、発生する理由は、誤ったcfsqltype
を使用しているためです。 パラメータ用。したがって、実際には、考えているものとは異なる値をデータベースに送信しています(したがって、異なる比較を実行しています)。その結果、クエリは一致するレコードを見つけることができません。そのため、グラフは空白になります。
cf_sql_timestamp
を使用する 「値」を完全な日付/時刻オブジェクトに変換しています。ただし、 YEAR() 4桁の数字のみを返します。つまり、リンゴとオレンジを比較しているのです。概念的には、クエリは実際にこれを行っています:
WHERE 2014 = {ts '2009-02-13 23:31:30'}
エラーをスローしない理由は、日付/時刻の値が内部で数値として格納されるためです。つまり、実際には、小さい数(つまり、年)と実際に大きい数(つまり、日付/時刻)を比較しています。明らかに、日付の値ははるかに大きくなるため、年の数値と一致することはほとんどありません。繰り返しますが、概念的に クエリはこれを行っています:
WHERE 2014 = 1234567890
cfsqltypeはオプションであるため、多くの人はそれはそれほど重要ではないと考えていますが、重要です。
-
検証: 他の利点に加えて、cfqueryparamは、
cfsqltype
に基づいて、提供された「値」を検証します。 (日付、日時、番号など)。これは前に発生します SQLはデータベースに送信されます。したがって、入力が無効な場合でも、データベース呼び出しを無駄にすることはありません。 cfsqltypeを省略するか、デフォルトのie文字列を使用すると、余分な検証が失われます。 -
精度 適切なcfsqltypeを選択すると、データベースに正しい値を送信できます。上で示したように、間違ったタイプを使用すると、CFがデータベースに間違った値を送信する可能性があります。
cfsqltype
また、値が明確な形式でデータベースに送信されるようにし、データベースが期待どおりに解釈するようにします。技術的には、すべてをデータベースに文字列として送信できます。ただし、これにより、データベースは暗黙的な変換> (通常は望ましくありません)。暗黙の変換では、文字列の解釈は完全にデータベースに任されます-そしてそれはあなたが期待する答えを常に思い付くとは限らないかもしれません。日付オブジェクトではなく文字列として日付を送信することは、その代表的な例です。現在のデータベースは「2014年5月4日」のような日付文字列をどのように解釈しますか? 4月5日または5月4日として?場合によります。データベースまたはデータベース設定を変更すると、結果が完全に異なる場合があります。
一貫した結果を保証する唯一の方法は、適切なcfsqltypeを指定することです。比較列/関数のデータ型、または少なくとも同等の型と一致する必要があります。 YEAR()
の場合 、4桁の数値を返します。したがって、cf_sql_integer
を使用する必要があります 、エイドリアンがコメントに言及したように
。同じことが
WHERE Year(ColumnName) = <cfqueryparam value="2014" cfsqltye="CF_SQL_INTEGER">
AND Month(ColumnName) = <cfqueryparam value="11" cfsqltye="CF_SQL_INTEGER">
以上のことをすべて述べましたが、ダンの提案
日付の比較を実行するためのより良い方法です。 そのパラダイム
よりインデックスに対応し、ターゲット列に日付(のみ)または日付と時刻が含まれているかどうかに関係なく機能します。 cf_sql_date
の使用に注意してください 彼の例では。
-
cf_sql_timestamp
-日付と時刻の両方を送信します -
cf_sql_date
-日付のみを送信します。時間の値は切り捨てられます