11

ColdFusion でコーディングしていますが、cfscript にとどまろうとしているので、クエリを渡して実行できる関数があります。 <cfquery blah > #query# </cfquery>

どういうわけか、クエリを で作成しsql = "SELECT * FROM a WHERE b='#c#'" て渡すと、ColdFusion は一重引用符を 2 つの一重引用符に置き換えました。そのため WHERE b=''c''、最終的なクエリになります。

文字列をさまざまな方法で作成しようとしましたが、引用符を1つだけ残すことはできません。文字列を置き換えても効果はありません。

なぜこれが起こっているのですか?このプロジェクトの期間中、cfscript で生活するという私の希望が台無しになっています。

4

4 に答える 4

18

設計上、ColdFusionは、<cfquery>タグ内の変数を補間するときに一重引用符をエスケープします。

あなたがやりたいことをするために、あなたはPreserveSingleQuotes()関数を使う必要があります。

<cfquery ...>#PreserveSingleQuotes(query)#</cfquery>

ただし、これは、自分自身をさらしているSQLインジェクションの危険性には対処していません。

を使用<cfqueryparam>すると、データベースでクエリをキャッシュすることもできます。これにより、ほとんどの場合、パフォーマンスが向上します。

を使用する利点の詳細については、古いベンフォルタのコラムブラッドウッドによる最近の投稿を読むと役立つ場合があります<cfqueryparam>

于 2008-11-05T21:10:25.370 に答える
6

他の人が言っているように、あなたの質問への答えは使用していますpreserveSingleQuotes(...)

ただし、実際に必要な解決策は、この方法でクエリを動的に構築することではありません。それは悪い悪い悪いです。

SQLをcfqueryタグ内に配置し、必要に応じてifs / switchs / etcを使用して、すべてのCF変数がcfqueryparamタグを使用するようにします。

(ORDER BY句で変数を使用する場合は、変数を手動でエスケープする必要があることに注意してください。cfqueryparamはORDER BY句では使用できません)

于 2008-11-05T23:09:04.460 に答える
4

<cfquery>次の構文を使用すると、ColdFusionはタグ内の一重引用符を自動的にエスケープします。

SELECT * FROM TABLE WHERE Foo='#Foo#'

一重引用符を保持したい場合は、#Foo#を呼び出す必要があります#PreserveSingleQuotes(Foo)#

自動エスケープは変数値に対してのみ機能し、関数の結果に対しては機能しないことに注意してください。

SELECT * FROM TABLE WHERE Foo='#LCase(Foo)#' /* Single quotes are retained! */

その観点から、関数PreserveSingleQuotes()Adobe LiveDocsを参照)は、値に対する「null操作」にすぎません。つまり、自動エスケープをバイパスする関数の結果に変換します。

于 2008-11-05T21:32:58.367 に答える
0

彼は良い仕事をしたと思ったので、私はデイブの答えに投票しました。

ただし、ColdFusion 用に設計されたいくつかの異なるツールもあり、実行する可能性が高い多くの一般的な SQL タスクを簡素化できることを付け加えたいと思います。Steve Bryant によって書かれたDataMgrと呼ばれる非常に軽量なツールと、Mark Mandel のTransfer 、 Doug Hughes によって最初に作成されたReactor 、および私が開発したDataFaucetと呼ばれるツールがあります。これらにはそれぞれ独自の長所と短所があります。個人的には、DataFaucet は、さまざまな種類のクエリを作成するためのさまざまな構文を使用して、cfscript にとどまる最良の機能を提供するものであると考える傾向があると思います。

以下にいくつかの例を示します。

qry = datasource.select_avg_price_as_avgprice_from_products(); //(requires CF8)

qry = datasource.select("avg(price) as avgprice","products"); 

qry = datasource.getSelect("avg(price) as  avgprice","products").filter("categoryid",url.categoryid).execute();

qry = datasource.getSelect(table="products",orderby="productname").filter("categoryid",url.categoryid).execute();


フレームワークは、sql-injection 攻撃を防ぐために、これらのフィルター ステートメントで cfqueryparam が常に使用されることを保証します。insert、update、delete ステートメントには同様の構文があります。( sql-injection を回避するための簡単なルールがいくつかあります。)

于 2009-01-05T00:11:24.550 に答える