2

ユーザーに日付を選択してから送信するように求める HTML フォームがあります。送信時に、ColdFusion を使用して選択した日付の間のレコードを取得しようとしています。私のクエリは次のようになります。

SELECT  * 
FROM    user_activation_events
where   STATUS_CODE =1
AND     event_date >= #Dateformat(form.from_date, 'dd-mm-yyyy')#
AND     event_date <= #Dateformat(form.to_date, 'dd-mm-yyyy')#

ただし、日付は次の形式でデータベースに保存されるため、これは機能しません。

    yyyy-mm-dd hh:mm:ss

誰かがそれを行う方法を教えてもらえますか?

4

2 に答える 2

3

ここで起こっている問題がいくつかあります。_dateで終わるフォームフィールドは、フォーム検証基準です。したがって、フォームフィールドの名前をtodateとfromdateに変更する必要があります。次に、入力をサニタイズしようとしているのは良いことです。cfqueryparamそれを行うために使用されます。大事なことを言い忘れましたが、その間はよりクリーンなSQLです。クエリは次のようになります。

<cfif isDate(form.fromDate) AND isDate(form.toDate)>

    <cfquery name="qryUser_Activation_Events">
    SELECT * 
    FROM   user_activation_events
    WHERE  STATUS_CODE =1
    AND    event_date BETWEEN <cfqueryparam cfsqltype="CF_SQL_date" value="#form.fromDate#">
        AND DATEADD(d, 1, <cfqueryparam cfsqltype="CF_SQL_date" value="#form.toDate#">)
    ORDER BY ...
    </cfquery>

<cfelse>  
    <!--- Error handling goes here --->
</cfif>
于 2012-12-02T06:32:37.753 に答える
1

コメントで示唆されているように、日付をフィルタリングするより柔軟な方法は、このアプローチを使用することです。列に日付のみが含まれているか、日付と時刻が含まれているかに関係なく機能し、データベースのインデックスの使用を妨げません (日付関数を使用する場合と同様)。

    WHERE  TheDateColumn >= TheStartDateAtMidnight         
    AND    TheDateColumn < TheDayAfterEndDateAtMidnight   

たとえば、2012 年 12 月 3 日から 12 月 4 日までの日付のすべてのレコードを返す場合は、次のようにします

<!--- omitted date validation for brevity ---> 
<cfset form.from_date = "12/03/2012">
<cfset form.to_date   = "12/04/2012">

<cfquery name="getEvents" datasource="#dsn#">
    SELECT  event_date
    FROM    user_activation_events 
    WHERE   event_date >= <cfqueryparam value="#form.from_date#" cfsqltype="cf_sql_date">
    AND     event_date < <cfqueryparam value="#dateAdd('d', 1, form.to_date)#" cfsqltype="cf_sql_date">
    AND     status_code = 1 
</cfquery>


サンプルデータ

    2012-12-02 23:59:59.000
    2012-12-03 00:00:00.000
    2012-12-03 07:34:18.000
    2012-12-04 13:34:18.000
    2012-12-04 23:59:59.000
    2012-12-05 00:00:00.000

結果:

    1 | 2012-12-03 00:00:00.0  
    2 | 2012-12-03 07:34:18.0  
    3 | 2012-12-04 13:34:18.0  
    4 | 2012-12-04 23:59:59.0  



日付に関する注意:

ただし、日付は次の形式でデータベースに保存されるため、これは機能しません: yyyy-mm-dd hh:mm:ss

それは本当にフォーマットとは何の関係もありません。日時の値は、画面に表示される方法では保存されません。これyyyy-mm-dd hh:mm:ssは、使用している IDE によって表示されるユーザー フレンドリーな文字列であり、さまざまです。通常、datetime値は実際には数値として格納されます。この数値は通常、ある基準日またはエポックからのオフセットを表します。CF/Java では、UNIX エポックからのミリ秒数です。そのため、IDE では のようなわかりやすい日付文字列が表示される場合がありますがyyyy-mm-dd hh:mm:ss、内部的には単なる数字です。

日付クエリは、数値比較のようなものと考えてください。クエリが期待するすべてのレコードを返さない場合は、通常、渡す数値の 1 つが大きすぎるか小さすぎることが原因です。

 WHERE Col >= 1354510800000   // java.util.Date => {ts '2012-12-03 00:00:00'}
 AND   Col <= 1354683600000   // java.util.Date => {ts '2012-12-05 00:00:00'}
于 2012-12-03T15:59:26.557 に答える