1
votes

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?

3
Aside from all hell breaking loose, what is your error? - Evik James
@EvikJames I'm not on site but will post error details within 24 hrs. - Celeritas
The error that you posted has nothing to do with cfqueryparam, but instead the referential integrity of your database. The error isn't even happening in the code you provided above. The query as you have it above shouldn't work anyway since there are 3 columns you're inserting to, but only 2 that you've specified values for. - nosilleg
@nosilleg the error only occurs when I add <cfqueryparam>s to the code I mentioned. ColdFusion doesn't always report the correct line in the sense if a SQL error occurs it may report the line which the closing <cfquery> tag is on. But you think there's something wrong with the database? I'm definitely not an expert at this - Celeritas
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_WelcomeHome_TSupplier"... means that you're trying to put a value in the SupplierID column that doesn't exist as a primary key in the main table. But your code above doesn't mention SupplierID, so I can't see exactly where it's going wrong. Maybe the relationship itself is wrong and you've bound SurveyID to SupplierID or something similar. - nosilleg

3 Answers

4
votes

<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

2
votes

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.

0
votes

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?