我正在使用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类型解决方案,就像我之前提到的问题/解决方案一样。我试着像第一个一样直接包含它,但我在代码中遇到编译错误。任何想法或提示都会有所帮助,谢谢。
答案 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。其中两个最重要的好处是:
绑定变量通过阻止文字值作为SQL命令执行来帮助防止sql injection。这可以保护数据库免受包含恶意制作的SQL的值的影响。
对于多次执行的查询,绑定变量还通过鼓励数据库重用执行计划来提高性能。否则,数据库可以选择在查询参数改变时生成新的执行计划,这是昂贵的。
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>