Tuesday, November 1, 2011

Null Values within SQL Select Statement with CFQUERYPARAM

I was working on code where I wanted to store nulls into the database and query based on those nulls.

<cfquery name="qRetrieve" datasource="#getDSN().getName()#">
 select semesterID,Major_ID,Campus_ID,AdmTypeReqID,startDate,startOrEndFlag
 from isFull
  semesterID = <cfqueryparam value="#arguments.DTO.getsemesterID()#" cfsqltype="CF_SQL_INTEGER">
  AND Campus_ID = <cfqueryparam value="#arguments.DTO.getCampus_ID()#" cfsqltype="CF_SQL_INTEGER">
  AND startOrEndFlag = <cfqueryparam value="#arguments.DTO.getstartOrEndFlag()#" cfsqltype="CF_SQL_INTEGER">
  AND AdmTypeReqID= <cfqueryparam value="#arguments.DTO.getAdmTypeReqID()#" cfsqltype="CF_SQL_INTEGER" null="#iif(arguments.DTO.getAdmTypeReqID(),true,false)#">

Notice the last line is using the function IIF instide the null attribute of cfqueryparam.  In the SQL Insert and Update statements, this just works.  I am noticing in interacting with MSSQL 2005 this is not working.  I am getting zero rows back when it should be in the 5-10 rows. For now I have replaced my last line of code with the following 5 rows of code

   <cfif arguments.dto.getAdmTypeReqID() EQ "">
   AdmTypeReqID is null
   AdmTypeReqID = <cfqueryparam value="#arguments.DTO.getAdmTypeReqID()#" cfsqltype="CF_SQL_INTEGER" >

Has anyone else ran into this?


  1. Is it possible that "arguments.DTO.getAdmTypeReqID()" is returning a numeric value 0 instead of a blank value? That IIF() also looks backward to me. If arguments.DTO.getAdmTypeReqID() evaluates to true, then null="true" - is that correct? I would expect it to say: #IIF(arguments.DTO.getAdmTypeReqID(),false,true)# meaning "if arguments.DTO.getAdmTypeReqID() is true, then 'not null' ". Maybe I'm just not understanding the intent.

  2. That's expected behavior under The SQL-92 standard.

    NULL is a special value reprenting the unknown, it's not equal to anything as you don't know what it is... we all are tempted to say but it's NULL, but the power that be don't agree ;)

    You can say {column} is unknown this can evaluate to a logical condition

    but you can't say {column} = unknown this will always be false as you compare known with unknown.

    You can override this behavior with the SET ANSI_NULLS {ON | OFF} instruction but I wouldn't recommend it.


  3. There's no need to use iif()--which has some performance issues. Just do:

    <cfqueryparam value="#arguments.DTO.getAdmTypeReqID()#" cfsqltype="CF_SQL_INTEGER" null="#(arguments.DTO.getAdmTypeReqID())#">

  4. This comment has been removed by the author.

  5. Why dont you do something like this:

    <cfqueryparam value="#arguments.DTO.getAdmTypeReqID()#" cfsqltype="CF_SQL_INTEGER" null="#NOT isNumeric(arguments.DTO.getAdmTypeReqID())#">

  6. Thanks for all the great comments, I would like to clear one thing up, I actually mis-typed the example. I was actually comparing it to blank "" in the null attribute, so the last example is probably the best solution which i probably switch my code too. Other than that, I believe JF is right, it is just frustrating that we can use the same concept in SELECT statements as we do in UPDATE,INSERT,DELETE.

    Thanks everyone for great feedback, sometimes I wonder if anyone watches my blog :-D (PS. thanks coldfusionblogger.org for aggregating)

  7. Talend Online Training
    Introduction to Talend
    Why Talend?
    Talend Editions and Features
    Talend Data Integration Overview
    Talend Environment
    Talend Environment - Overview
    Repository and Pallate
    Talend Design and Views
    21st Century providing Online training and support on All Technologies. If you are seeking training and support you can reach me on 91-7386622889. Online training by real time Experts. Call us 001-309-200-3848 for online training