如何将日期从coldfusion变量插入到sql字段?

时间:2014-11-02 20:44:46

标签: sql sql-server datetime coldfusion

由于代码设置异常,而不是将cfquery与cfparam标记一起使用,而是构建一个sqlInsertCols列表和一个sqlInsertValues列表,并在insert语句中使用它们。代码如下:

<cfscript>
   var sqlInsertCols = "";
   var sqlInsertValues = "";
   // some looping and other processing here to fill the lists
   ...
</cfscript>

<cfquery datasource="..." name="insert">
   INSERT INTO MyTable(#sqlInsertACols#)
   VALUES (#sqlInsertVals#)
</cfquery>

首先,是否存在任何安全问题,考虑到这两个sql字符串都填充在此代码中而不是基于任何用户输入?

这适用于我插入的几个字段,但我只是尝试添加日期字段,并且无法使插入工作。日期的格式为&#34; mm / dd / yyyy&#34;。将日期添加到sql列表的代码:

sqlInsertCols = ListAppend(sqlInsertCols, "MyDateField");
sqlInsertValues = ListAppend(sqlInsertValues, myDateVar);

运行时没有错误,但db中的值为1900-01-01 00:00:00.000

我尝试在日期周围添加引号,但似乎无法正确插入。有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:1)

SQL Server在日期周围使用单引号。你试过那些吗?

答案 1 :(得分:1)

首先让我说我不喜欢这种做法。您似乎正在尝试将cfquery用作通用包装器 - 一种插入&#34;插入&#34;变量列表。这会使您的查询被其他代码遮挡。看到查询是最易受攻击的向量,更不用说通常包含用户输入,它会使一切更难以排除故障。此外,cfquery是CF语言的 strength - 您可以从DB IDE中剪切和粘贴的少数几种语言之一,并且可以简单地更改变量输入(当然,添加cfqueryparam)。

最后,您的查询需要使用cfqueryparam来保护SQLi - 所以在回答问题的最后部分时 - 是的,这段代码很容易受到攻击。很少有人不使用cfqueryparam。

所以...这里是一个解决方案(我再也不喜欢或推荐:)你可以作为一个起点:

<cfscript>
   var sqlInsertCols = "";
   var sqlInsertValues = "";
   // some looping and other processing here to fill the lists
   ...
</cfscript>

<cfquery datasource="..." name="insert">
   INSERT INTO MyTable(#sqlInsertACols#)
   VALUES (
    <cfloop list="#sqlinsertValues#" index="colVal">
        <cfif isDate(colVal)>
            <Cfqueryparam cfsqltype="CF_SQL_DATE" value="#colval#"/>
        <cfelse>
            <cfqueryparam cfsqltype="CF_SQL_CHAR" value="#colval#"/>
        </cfif>
    <cfif colVal IS NOT listlast(sqlInsertValues)>
              ,
       </cfif>
    </cfloop>

   )
</cfquery>

这假定标识为日期的字段正在插入类型为&#34; date&#34;的DB中的列中。它还假设所有&#34;其他&#34;非日期字段是字符字段。您可能需要添加对数字或整数或数据中的任何内容的检查。

此外,如果您需要根据值检查列名,可以使用listgetat,如下所示:

<cfscript>
   var sqlInsertCols = "";
   var sqlInsertValues = "";
   // some looping and other processing here to fill the lists
   ...
</cfscript>

<cfquery datasource="..." name="insert">
   INSERT INTO MyTable(#sqlInsertACols#)
   VALUES (
    <cfloop from="1" to="#listlen(sqlinsertValues)#" index="x">
        <cfif listgetat(sqlInsertCols,x) IS 'dateadded'>
            <Cfqueryparam cfsqltype="CF_SQL_DATE" value="#listgetat(sqlInsertValues,x)#"/>
        <cfelseif listgetat(sqlInsertCols,x) IS 'userid'>>
            <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#listgetat(sqlInsertValues,x)#"/>
        </cfif>

       <cfif x IS NOT listlen(sqlInsertValues)>
            ,
          </cfif>

    </cfloop>
   )
</cfquery>

最后,对于完全不推荐的快速和脏的解决方案,您可以试试这个:

<cfscript>
   var sqlInsertCols = "";
   var sqlInsertValues = "";
   // some looping and other processing here to fill the lists
   ...
</cfscript>

<cfquery datasource="..." name="insert">
   INSERT INTO MyTable(#sqlInsertACols#)
   VALUES (
    <cfloop list="#sqlinsertValues#" index="colVal">

        '#colval#'
            <cfif colVal IS NOT listlast(sqlInsertValues)>
                  ,
           </cfif>
    </cfloop>

   )
</cfquery>

这可能有效,因为你的RDBMS隐式转换 - 在很多/大多数情况下可以从字符到日期,int或数字转换。当然,你可能很容易得到语法错误。

最后一点:上面的第一个和第三个示例使用一些简单的方法在列表中插入逗号 - 将值与列表中的最后一个值进行比较,如果它们不匹配则插入。因此,这假设列表中不是最后的任何项目与列表中的最后一项不同。如果最后一项在查询中的位置重复,那么您将收到缺少逗号的语法错误。祝你好运!

勘误表: 仅供参考 - 在最后一个片段上 - 单引号OUTSIDE变量不会被CFQUERY转义..所以当你使用&#39; #varName#&#39; - 单引号被保留,但当它们在变量中时它们被转义 - 因为CF自然地假设(并且最佳实践指示)你正在处理以变量形式插入的内容,而不是查询语言本身。