どのようにご利用ですか?cfqueryparam、ORDER BY句?
-
23-08-2019 - |
質問
ようにしていきの良いCFでウェブ-デベロッパーと利用 <cfqueryparam>
周りのすべての形のURLを構成する各要素をもったSQLクエリ.
この場合、このようにしているユーザを制御するORDER BY句ます。
<cfquery datasource="MyDSN" name="qIncidents">
SELECT IncidentID, AnimalID, IntakeDate, DxDate, OutcomeDate
FROM Incidents
WHERE ShelterID = <cfqueryparam cfsqltype="cf_sql_integer" value="#Arguments.ShelterID#">
ORDER BY <cfqueryparam cfsqltype="cf_sql_varchar" value="#SortBy#">
</cfquery>
私はこの人にとっては、以下のようなエラー:
の選択によって識別される項目の順に1番を含む変数の一部として発現を特定するカラム位置にします。変数の場合に限り認められるべき順序付けによる表現を参照カラムの名前です。
他の方法についています。
解決
残念ながら、あなたは、ORDER BY句で直接CFQUERYPARAMを使用することはできません。
あなたが動的にまだ安全にそうすることで受注を使用したい場合は、、あなたはいくつかの条件(たとえば、URL変数)に応じて、あなたのSORTBY変数を変更するCFSWITCHまたは類似の構造を設定することができます。いつものように、単にユーザーの入力を見て、それに基づいて、可能な値の所定のリストから選択し、ユーザーから直接任意の値を渡しません。すると、ちょうど標準の構文を使用します:
ORDER BY #SortBy#
他のヒント
私はただアーロンの答えに拡大します。
:私が行うことの一つは、ORDER BY句に渡された引数が有効であることを確認するためにlistfindnocase()を使用することです<cfset variables.safeSortColumn = "name">
<cfset variables.safeSortOrder = "desc">
<cfparam name="url.sortcolumn" type="string" default="#variables.safeSortColumn#">
<cfparam name="url.sortorder" type="string" default="#variables.safeSortOrder#">
<cfif listfindnocase("name,age,address", url.sortcolumn)>
<cfset variables.safeSortColumn = url.sortcolumn>
</cfif>
<cfif listfindnocase("desc,asc", url.sortorder)>
<cfset variables.safeSortOrder = url.sortorder>
</cfif>
<cfquery>
select *
from mytable
order by #variables.safeSortcolumn# #variables.safeSortorder#
</cfquery>
コラム参照の順序値を使用しての問題は、CREATE TABLEのSQL文が実行された時点で序数値(私は信じている)、それをですあなたは、実際の順序値を表していない可能性が列を表示するために使用します。私は本当にこのためでcfqueryparamを使用することから離れて滞在する。
私はソートする列を指定して、スイッチでそれを使用して、実際の列名にそれを翻訳するリクエスト変数の数値(URL、フォーム)を使用してのアイデアが好きですか - あなたはあなたのコラムを公開いけませんユーザーの名前。
限り理由(それは非常に素晴らしいボーナスがあるが)そのだけではなく、入力の検証及び防止SQLインジェクションについて覚えておいて、でcfqueryparamを使用する際に/など - でcfqueryparamでデータベースへの基本的なSQLをドライバを介して送り返されます製品FROM WHERE ID = 1 SELECT *とSELECT * WHERE製品FROM:あなたはこのようなSQL文を送信するときdatabseオプティマイザはそう...より一般的な形式で使用するインデックスを決定することができますので、プレースホルダの値 - SQLのバインド変数を使用してID = 2オプティマイザは両方の時間を実行します。しかし、バインド変数で、SQLは=製品FROM WHERE ID *このSELECTのように見えますか? (?= 1)とSELECT * FROM製品WHERE ID =? (?= 2)ので、オプティマイザはインデックスが2番目のクエリに使用するために正確に把握するために最初の解析結果のキャッシュを使用することができます。 SQLの複雑さやデータベースに応じて、これは時間が大幅に節約することができます。 where句では、Oracleおよび日付/時刻の列を持つ賢明な私の経験の非常に役立つパフォーマンスでます。
これまででcfqueryparamを使用する場合など、そのSQLのバインド変数を使用することができますどこ...
HTH JON
についての解説を"cfqueryparamの条項とは、MySQL".ああ、と思っていただいて結構でMySQLデータソースを.ものを列 序, ないカラム名(うとして処理する一定の文字列ます。
残念ながらないように作ってMS SQLデータソースを.少なくともないからこそできます。
<!--- this works --->
<cfset url.sortColumnNumber = "3">
<cfquery name="getDataByPosition" datasource="MySQLDSN">
SELECT RecordID, ProductName, DateAdded
FROM TestTable
ORDER BY <cfqueryparam value="#url.sortColumnNumber#" cfsqltype="cf_sql_integer"> ASC
</cfquery>
<cfdump var="#getDataByPosition#">
<!--- this does NOT work --->
<cfset url.sortColumnName = "DateAdded">
<cfquery name="getDataByName" datasource="MySQLDSN">
SELECT RecordID, ProductName, DateAdded
FROM TestTable
ORDER BY <cfqueryparam value="DateAdded" cfsqltype="cf_sql_varchar"> ASC
</cfquery>
<cfdump var="#getDataByName#">
更新: に関するコ序:ないことを指すカラムの選択リストではなく、配下の表に示す。でなければならないと考えてます。
その通りであsqlインジェクション保護を主な目的cfqueryparam.その内容結合する変数をいいます。
私はこの問題では、より少ないコードを投げるだろうと思ってます:
<cfset sortColumns = {IncidentID = "IncidentID", AnimalID = "AnimalID", IntakeDate = "IntakeDate", DxDate = "DxDate", OutcomeDate = "OutcomeDate"}>
<cfset sortDirections = {ASC = "ASC", DESC = "DESC"}>
<cfquery datasource="MyDSN" name="qIncidents">
SELECT IncidentID, AnimalID, IntakeDate, DxDate, OutcomeDate
FROM Incidents
WHERE ShelterID = <cfqueryparam cfsqltype="cf_sql_integer" value="#Arguments.ShelterID#">
ORDER BY #sortColumns[sortBy]# #sortDirections[sortDirection]#
</cfquery>
SORTBYとsortDirectionはURLまたはどこ史上経由で来るところます。
それはきれいだし、あなたはORDER BY句を経由して何を注入することはできませんので、私はこれが好きです。
すべてのコメント?