查询 - 字符串文字太长ORA错误

时间:2016-06-06 17:20:15

标签: oracle coldfusion coldfusion-11

我正在使用Cold Fusion 11 *,我收到以下错误:

ORA-01704: string literal too long.

首先,我收到了这个错误,并在通过更改我的代码来查看多个网站后对其进行了更正:

<cfquery datasource="#dsn#">
    update paragraphs
    set paragraph_text = #input#
    where  paragraph_id=#rs_d.paragraph_id#
</cfquery>

致:

<cfquery datasource="#dsn#">
    update paragraphs
    set paragraph_text = <cfqueryparam cfsqltype="CF_SQL_CLOB" value=#input#> 
    where paragraph_id=#rs_d.paragraph_id#
</cfquery>

该修复工作完美无缺。现在我得到了同样的错误,但我没有使用cfquery,而是在使用它之前将sql查询构建成一个字符串。所以这就是代码的外观:

sql = "insert into log (LOG_ENTRY_ID, program_id, paragraph_id, action, userid,";
sql = sql & " paragraph_text_old, paragraph_text_new, comment_id, current_program_status, new_program_status)";
sql = sql & " values (1 ," & program_id & ",";
if (paragraph_id neq ""){
    sql = sql & paragraph_id & ",";
}
else{
    sql = sql & " null,";
}
sql = sql & "'" & action & "',";
sql = sql & userid & ", '";
sql = sql & DoubleSingleQuotes(paragraph_text_old) & "','";
sql = sql & DoubleSingleQuotes(paragraph_text_new) & "',";
if (comment_id neq ""){
    sql = sql & comment_id & ",";
}
else{
    sql = sql & " null,";
}
if (current_program_status neq ""){
    sql = sql & "'" & current_program_status & "',";
}
else{
    sql = sql & " null,";
}
if (new_program_status neq ""){
    sql = sql & "'" & new_program_status & "'";
}
else{
    sql = sql & " null";
}       
sql = sql & ")";
   cfstmt(sql);

---结束功能

<cffunction name="cfstmt">
    <cfargument name="sql">
    <cfquery name="rs" datasource="#dsn#">
        #PreserveSingleQuotes(sql)#
    </cfquery>
</cffunction>

错误原因是old_paragraph_text和new_paragraph_text。我想知道是否有可能在这个问题中包含一个cfqueryparam类型解决方案,就像我之前提到的问题/解决方案一样。我试着像第一个一样直接包含它,但我在代码中遇到编译错误。任何想法或提示都会有所帮助,谢谢。

3 个答案:

答案 0 :(得分:1)

我建议重新安排你的逻辑来确定field null变量,然后在cfqueryparam的null属性中使用它们。像这样:

<cfscript>
fieldOneNull = conditionForNull ? true : false;
fieldTwoNull = conditionForNull ? true : false;
etc
</cfscript>

<cfquery>
insert into table
(field1, field2, etc)
values
(
<cfqueryparam cfsqltype="cf_sql_whatever" value="something" null="#fieldOneNull#">
, <cfqueryparam cfsqltype="cf_sql_whatever" value="something" null="#fieldTwoNull#">
, etc
)

答案 1 :(得分:1)

(评论太长)

  

希望限制代码,而不是确定空值   在查询之外,我添加了case语句

老实说,它并没有节省太多,因为代码实际上是以if / else的方式执行。除了现在,工作是在数据库端完成的,而不是它所属的应用服务器。

与许多遗留应用程序合作后,我意识到它们经常包含您可能会委婉地称之为&#34;可疑的&#34;代码;-)但是,你应该从不在SQL中使用原始客户端变量。除非您有充分的理由不这样做,否则请始终使用cfqueryparam

在内部,cfqueryparam使用bind variables。其中两个最重要的好处是:

  1. 绑定变量通过阻止文字值作为SQL命令执行来帮助防止sql injection。这可以保护数据库免受包含恶意制作的SQL的值的影响。

  2. 对于多次执行的查询,绑定变量还通过鼓励数据库重用执行计划来提高性能。否则,数据库可以选择在查询参数改变时生成新的执行计划,这是昂贵的。

  3. CFQueryparam还有一些其他不错的功能,例如&#34; null&#34;属性。当满足某些条件时,它可用于提交null值。

    最后,就最佳实践而言,完全确定所有变量的范围也是一个好主意。因此,例如,如果变量是在FORM范围内提交的,那么最终查询可能看起来像这样某些。 (根据需要修改cfsqltypes。)

    <cfquery datasource="#variables.dsn#">
      INSERT INTO into log (
        program_id
        , paragraph_id
        , userid
        , action
        , paragraph_text_old
        , paragraph_text_new
    )
    VALUES 
    (
        <cfqueryparam value="#FORM.program_id#" cfsqltype="CF_SQL_INTEGER">
        , <cfqueryparam value="#FORM.paragraph_id#" cfsqltype="CF_SQL_INTEGER" null="#NOT IsNumeric(FORM.paragraph_id)#">
        , <cfqueryparam value="#Session.userid#" cfsqltype="CF_SQL_INTEGER">
        , 'Paragraph Updated' 
        , <cfqueryparam cfsqltype="CF_SQL_CLOB" value="#rs_d.paragraph_text#">
        , <cfqueryparam cfsqltype="CF_SQL_CLOB" value="#FORM.input#"> 
    )
    </cfquery>  
    

    注意:除非分配了不同的默认值,否则在NULL列表中省略该列时,系统会自动插入INSERT

答案 2 :(得分:0)

感谢您的建议。我没有修改在应用程序的不同区域中使用的现有函数,而是在调用函数的位置添加了一个新的insert语句来处理clobs。为了处理空字段,我使用了case语句。

<cfquery datasource="#dsn#">
    insert into log (
        LOG_ENTRY_ID, program_id, paragraph_id, userid, action, paragraph_text_old
       , paragraph_text_new, comment_id, current_program_status, new_program_status
    )
    values (
        null ,#program_id#,(case when #paragraph_id# = '' then null else #paragraph_id# end)
       , #Session.userid# , 'Paragraph Updated'
       , <cfqueryparam cfsqltype="CF_SQL_CLOB" value=#rs_d.paragraph_text#>
       , <cfqueryparam cfsqltype="CF_SQL_CLOB" value=#input#> 
       , null, null , null
    )
</cfquery>