Je reçois l'erreur suivante et ne peux pas comprendre pourquoi:
Erreur lors de l'exécution de la requête de database. [Macromedia] [Pilote JDBC SQLServer] [SQLServer] Syntaxe incorrecte près de ')'. L'erreur est survenue à la ligne 141.
<cfquery datasource="mySource" name="getTravel"> select traveler, customernumber, destination, sortingpdate, purpose, empid, pm_reportid, company from mySource.dbo.PM_Travel where pm_reportid in ( <cfloop from="1" to="#getRecentReports.recordcount#" index="i"> <cfif i lt getRecentReports.recordcount> #getRecentReports.pm_reportid[i]#, <cfelse> #getRecentReports.pm_reportid[i]# </cfif> </cfloop> ) order by customernumber </cfquery>
La ligne 141 est:
where pm_reportid in (<cfloop from="1" to="#getRecentReports.recordcount#" index="i"><cfif i lt getRecentReports.recordcount>#getRecentReports.pm_reportid[i]#, <cfelse>#getRecentReports.pm_reportid[i]#</cfif></cfloop>)
Cela n'a pas été écrit par moi, et je suis nouveau à CF. Toute aide est appréciée.
Essaye ça:
where pm_reportid in ( <cfqueryparam value="#valueList(getrecentReports.pm_report_id)#" list="true" cfSqlType="CF_SQL_NUMERIC" /> )
Vous devrez peut-être modifier la valeur de cfSqlType
pour qu'elle corresponde au type de données contenu dans la colonne "pm_report_id". Si c'est du text, essayez d'utiliser CF_SQL_VARCHAR
Pour expliquer ce qui se passe:
valueList()
prend une colonne de requête, dans la syntaxe de 'queryName.columnName', et la convertit en une list délimitée par des virgules.
cfqueryparam
paramètre la requête qui vous donnera une amélioration des performances du côté SQL et offre un peu de security lorsque datatables sont transmises en tant que certain type de données.
(Suivi des commentaires)
Comme je l'ai mentionné, le code cfloop génère probablement une instruction SQL invalide. Soit en raison de la requête contenant zéro (0) loggings, ce qui produirait une clause vide:
WHERE Col IN ( {nothing here} )
… ou l'un des identifiants est null, ce qui créerait une clause invalide avec des virgules supplémentaires, comme:
WHERE Col (11,22,33,{no value here},44)
La réponse de Scott montre une façon de gérer cela. Une autre option consiste à utiliser un JOIN au lieu de boucler les résultats de la requête. Il suffit de joindre les deux tables sur la (les) colonne (s) correspondante (s) et d'utiliser les filters WHERE
appropriés. Le SQL exact dépend de la relation entre les deux tables, mais ci-dessous est l'idée générale. Je ne connais pas les noms exacts ou les types de données des colonnes impliquées, donc modifiez-les si nécessaire.
<cfquery ....> SELECT t.traveler, t.customernumber, t.destination, ...more columns ... FROM PM_Travel t INNER JOIN pm_reports r ON t.pm_reportid = r.pm_reportid WHERE r.empID = <cfqueryparam value="#form.empid#" cfsqltype="cf_sql_integer"> AND r.weekID = <cfqueryparam value="#form.weekid#" cfsqltype="cf_sql_integer"> </cfquery>
Côté note, je sais que c'est une application héritée, mais assurez-vous d'utiliser cfqueryparam
sur toutes les valeurs fournies par l'user. Comme Scott l'a mentionné, à la fois pour améliorer les performances et pour fournir une couche supplémentaire de protection contre une forme commune d'injection sql. Vous pouvez find un mappage de cfsqltypes par dbms dans la documentation CF.