Skip navigation
Currently Being Moderated

Array in Where clause?

Sep 22, 2011 11:01 AM

I would like to create a Coldfusion function where one of my arguments is and array of "user_id"'s. Then I want to:

 

Select * from database where (each id in the array) = #user_id#

 

How is this written?

 
Replies
  • Currently Being Moderated
    Sep 22, 2011 11:09 AM   in reply to C-Rock

    Use a WHERE IN clause.  You can use the arrayToList() function to generate the list of user id's.

     

          http://www.w3schools.com/SQl/sql_in.asp

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 22, 2011 11:06 PM   in reply to C-Rock

    Hi,

     

    Please try this,

    Select * from database where user_id in( <cfqueryparam cfsqltype="cf_sql_integer"  list="true" value="#arraytoList(useridarray)#">)

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 23, 2011 3:27 PM   in reply to -==cfSearching==-

    Better yet, create a list instead of an array to start with.  Less processing that way.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 24, 2011 12:50 PM   in reply to C-Rock

    C-Rock wrote:

     

    I would like to create a Coldfusion function where one of my arguments is and array of "user_id"'s. Then I want to:

     

    Select * from database where (each id in the array) = #user_id#

     

    How is this written?

    <cffunction name="getDetails" returntype="query">

        <cfargument name="userIDs" type="array">

        <cfset var IDList = arrayToList(userIDs)>

        <cfquery name="details" datasource="myDSN">

        SELECT *

        FROM myTable

        WHERE id IN (#IDList#)

        </cfquery>

        <cfreturn details>

    </cffunction>

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 24, 2011 1:47 PM   in reply to BKBK

       WHERE id IN (#IDList#)

     

    Do not forget to use cfqueryparam to avoid sql injection. Also remember to scope query variables too.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 1:18 AM   in reply to -==cfSearching==-

    -==cfSearching==- wrote:

     

       WHERE id IN (#IDList#)

     

    Do not forget to use cfqueryparam to avoid sql injection. Also remember to scope query variables too.

    I would disagree. If there is a need to use cfqueryparam here, then the design is likely improper.

     

    User IDs don't usually come from users themselves. One may therefore assume that, by the time we arrive at an in-process like this one, the IDs have been validated and are kosher (or halal, as the case may be).

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 1:33 AM   in reply to BKBK

    I would disagree. If there is a need to use cfqueryparam here, then the design is likely improper.

     

    I would respectfully disagree with your disagreement

     

    *Any* variable should use params, so that the database engine can re-use its execution plan and so improve performance. They are not there only for protection from sql injection.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 1:49 AM   in reply to Owain North

    Owain North wrote:

     

    I would disagree. If there is a need to use cfqueryparam here, then the design is likely improper.

     

    I would respectfully disagree with your disagreement

     

    *Any* variable should use params, so that the database engine can re-use its execution plan and so improve performance. They are not there only for protection from sql injection.

    I would respectfully disagree with your disagreement. Protection against SQL injection is a must. However, your 'should' isn't a 'must'.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 1:58 AM   in reply to BKBK

    And I would respectfully disagree with your respectful disagreement with my respectful disagreement of your previous disagreement.

     

    I agree.

     

    There is no technical *need* to use params, if you're coming at them with a purely security-oriented approach, in this one situation, and the parameters have already been checked for type-safety, which I suspect they have not.

     

    I'm saying there is absolutely no downside to using them - it will be safer, quicker and type-safe. One of ColdFusion's (downsides|advantages, delete as appropriate) is its lack of type-safety. Although the function is, in this case, accepting an array, there is no way of checking what it's an array *of*. ColdFusion will happily try to pass strings into that SQL query. That array of IDs could easily have been populated into from a selection of HTML checkbox elements. All someone needs to do is change the value from an ID to a string in their browser and pow, you've got yourself a SQL Injection attack. I appreciate chances are it wouldn't work for various other reasons, but still - someone could easily get a string into your SQL query which is obviously a big no-no.

     

    You are saying that you should for some reason not bother with that for what reason? To save typing a few characters? In four years of working with ColdFusion I have never found a reason to pass a variable to a database unparam'd.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 2:49 AM   in reply to Owain North

    Cfqueryparam is handy in more ways than one. There is no argument about that (pun!). However, the context of my statement was clear: SQL injection.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 3:07 AM   in reply to BKBK

    I accept that, but I'm saying you're incorrect in that case. Take this example:

     

              CREATE TABLE Users (

                        Id INT PRIMARY KEY AUTO_INCREMENT,

                        Name VARCHAR(10) )

     

    <cffunction name="getDetails" returntype="query">

        <cfargument name="userIDs" type="array">

        <cfset var IDList = arrayToList(userIDs)>

          <cfquery name="details" datasource="mysql" result="res">

                  SELECT *

                  FROM Users

                  WHERE Id IN (#IDList#)

        </cfquery>

          <cfreturn details>

    </cffunction>

     

    <cfset aIDs = [1, 4, 5, 3, "0); UPDATE Users SET Name = 'hacked' WHERE Id NOT IN (1000"] />

    <cfset getDetails(aIDs) />

     

    The function has taken in an array, so that's not a problem - CF sends the query off to the db. However look what gets given to the database:

     

         SELECT * FROM Users WHERE Id IN (1,4,5,3,0); UPDATE Users SET Name = ''hacked'' WHERE Id NOT IN (1000)

     

    I just don't see the need to *ever* advise someone not to use queryparams, especially in such a weakly-typed environment.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 5:08 AM   in reply to Owain North

    @Owain North

    Your examples simply justify what you say. However, they don't necessarily amount to a contradiction of what I have said.

     

    I just don't see the need to *ever* advise someone not to use queryparams, especially in such a weakly-typed environment.

     

    No one is advising anyone not to use cfqueryparam. My point is, there is no need to protect against SQL injection for parameters that should already have undergone validation in the first place.

     

    In other words, having to do so should be a signal that something is amiss. In fact, I am assuming that the user IDs in the original question are coming from the database!

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 25, 2011 5:19 AM   in reply to C-Rock

    @C-Rock

     

    Should you be interested, the clause where the fuss is all about is:

     

    WHERE id IN (<CFQUERYPARAM VALUE="#IDList#" CFSQLTYPE="CF_SQL_INTEGER" LIST="yes">)

     

    I have assumed the user IDs are whole numbers.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 26, 2011 9:33 AM   in reply to BKBK

    Just catching up on email ..

     

    should already have undergone validation in the first

    place.

     

     

    Having an extra layer of security at such minimal cost is a good thing. So what if the checks might sometimes be redundant?  Given what bad things could easily happen if the input is not ideal, it is far better to err the side of safety. Add in cfqueryparam's other benefits and it makes more sense to use it than not. 

     

     

    -Leigh

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points