J'ai un formulaire HTML où je request à l'user de sélectionner des dates et de cliquer sur Envoyer. Lors de la soumission, j'essaie d'aller chercher des loggings entre les dates sélectionnées en utilisant Coldfusion. Ma requête ressemble à ceci:
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')#
Mais cela ne fonctionne pas car la date est stockée dans la database dans ce format: aaaa-mm-jj hh: mm: ss
Quelqu'un peut-il me dire comment faire?
Il y a quelques problèmes qui se posent ici. Tout champ de formulaire qui se termine par _date est un critère de validation de formulaire. Le champ de formulaire doit donc être renommé todate et fromdate. Ensuite, il est bon que vous essayez d'assainir l'input. cfqueryparam
est utilisé pour faire cela. Last but not least, entre est plus propre SQL Votre requête devrait ressembler un peu à:
<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>
Comme suggéré dans les commentaires, une façon plus flexible de filterr les dates est d'utiliser cette approche. Cela fonctionne indépendamment du fait que la colonne contienne des dates seulement ou des dates et heures et n'interfère pas avec l'utilisation d'index de la database (comme l'utilisation des fonctions de date peut).
WHERE TheDateColumn >= TheStartDateAtMidnight AND TheDateColumn < TheDayAfterEndDateAtMidnight
Par exemple, si vous souhaitez renvoyer tous les loggings datés du 12/3 au 12/4/2012:
<!--- 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>
Exemple de données
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
Résultats:
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
Mais cela ne fonctionne pas car la date est stockée dans la database dans ce format: aaaa-mm-jj hh: mm: ss
Cela n'a vraiment rien à voir avec le format. Les valeurs de date et d'heure ne sont pas stockées comme vous les voyez à l'écran. Le yyyy-mm-dd hh:mm:ss
est une string conviviale présentée par l'IDE que vous utilisez, et elle peut varier. Normalement, les valeurs datetime
sont réellement stockées en tant que nombres. Le nombre représente généralement un décalage par rapport à une date de base ou à une époque. Dans CF / java c'est le nombre millisecondes depuis l' époque unix . Donc, alors que votre IDE peut vous montrer une string de date conviviale pour l'homme comme yyyy-mm-dd hh:mm:ss
, en interne c'est juste un nombre.
Pensez aux requêtes de date comme toute comparaison numérique. Si la requête ne renvoie pas tous les loggings que vous attendez, c'est généralement parce que l'un des nombres que vous transmettez est trop grand ou trop petit.
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'}