質問

I'm trying to secure this code but every time I add cfqueryparam tags I get errors about parameter binding. I am certain I am setting the cfsqltype attribute to the right value. The last select statement is where all hell breaks loose.

<CFQUERY name="getLatestSurveyID" datasource="#REQUEST.dsn#">
    SELECT TOP 1
        SurveyID
    FROM
        TUser_WelcomeHome
    ORDER BY
        SurveyID DESC
</CFQUERY>


    <!--- Throw the Reasons/Subreasons into the DB --->
    <!---adding cfqueryparam tags breaks following CFIF block--->
<CFIF ListLen(SESSION.WHSurveyStruct.reasonString, ";") gt 0>
    <CFQUERY name="insertReasons" datasource="#REQUEST.dsn#">
        INSERT INTO TWelcomeHome_Reason
        (ReasonID, SubReasonID, SurveyID)
        SELECT #sanitize(ListFirst(SESSION.WHSurveyStruct.reasonString, ";"))#, #sanitize(getLatestSurveyID.SurveyID)# <!---error occures if adding cfqueryparam tags on this line--->
        <CFLOOP list="#sanitize(ListRest(SESSION.WHSurveyStruct.reasonString, ';'))#" index="thisReason" delimiters=";">
            UNION ALL
            SELECT #sanitize(thisReason)#, #sanitize(getLatestSurveyID.SurveyID)#
        </CFLOOP>

    </CFQUERY>

The above code works but if I did the following change it wouldn't work:
<cfqueryparam value=#sanitize(getLatestSurveyID.SurveyID)# cfsqltype="cf_sql_integer">

Here is the error caused by parametrization
<cfqueryparam value=#sanitize(getLatestSurveyID.SurveyID)# cfsqltype="cf_sql_integer">

Error Executing Database Query. [Macromedia][SQLServer JDBC Driver][SQLServer]The INSERT statement conflicted with the FOREIGN KEY constraint "FK_WelcomeHome_TSupplier". The conflict occurred in database "d21wca1", table "dbo.TSupplier", column 'SupplierID'. The error occurred in D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 215 Called from D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 183 Called from D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 174 Called from D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 1 Called from D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 215 Called from D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 183 Called from D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 174 Called from D:/Resource/www/dev/ww1test.owktravel.com/welcome_survey/welcome_survey_router.cfm: line 1 213 : #sanitize(SESSION.WHSurveyStruct.SupplierID)#NULL, 214 : #sanitize(SESSION.WHSurveyStruct.CruiselineID)#NULL, 215 : #sanitize(SESSION.WHSurveyStruct.UserID)# 216 : ) 217 :

EDIT: I'm stilling having trouble understanding what the loop is doing. Aren't the SELECT statements missing FROM?

役に立ちましたか?

解決

<cfqueryparam> cannot be used in a SELECT clause the way you are using it.

It can only be used in WHERE clause or part of a 'normal' INSERT or UPDATE

他のヒント

My explanation of how/when/why/etc to use <cfqueryparam> that I made here might help. I'll reproduce it here for ease of reference.

The thing to remember [...] is that there's two parts to an SQL statement: the SQL "commands", and the data being used by the SQL commands. Only the data can be parameterised. If you think about it, that makes sense: the SQL commands themselves are not "parameters".

One can think in a CF context here, for an analogy. Consider this statement:

<cfset variables.foo = "bar">

One could "parameterise" this with a passed-in value:

<cfset variables.foo = URL.foo>

(Where URL.foo is a parameter in this example)

But one could not expect to do this:

<#URL.tag# variables.foo = "bar">

(this is a very contrived example, but it demonstrates the point).

I think as far as the SQL in a <cfquery> goes, the waters are muddied somewhat because the whole thing is just a string in CF, and any part of the string can be swapped-out with a variable (column names, boolean operators, entire clauses, etc). So by extension one might think any variable can be replaced with a <cfqueryparam>. As we know now, this is not the case, as whilst it's all just a string as far as CF is concerned, it's considered code to the DB, so needs to conform to the DB's coding syntax.

I'm not sure why you're using that syntax for the SQL query. You can insert multiple rows of data using:

INSERT INTO myTable(column1, column2, column3)
VALUES('a','b','c'), ('d','e','f');

Since you can definitely use cfqueryparams within a VALUES clause. T think that should solve your problem. Just build the VALUES clause within your loop instead of all those SELECT/UNIONS. Would that work in your case?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top