每当 CF 抛出错误时,我都会收到一封包含所有异常信息的电子邮件。每次涉及数据库错误时我都会得到 SQL、WHERE 和 QueryError 信息,这很好。
SQL SELECT FooID FROM FooTable WHERE FooID = (param 1)
WHERE (param 1) = [type='IN', class='java.lang.Integer', value='47', sqltype='CF_SQL_INTEGER']
Error [Macromedia][SQLServer JDBC Driver][SQLServer]Insufficient clearance to break temporal directive.
但是,如果它是具有多个 cfqueryparams 的特定冗长查询,则搜索和替换参数以通过 MSSQL 运行相同查询会变得很麻烦。我一直希望能够以编程方式包含可复制的查询行,以便我可以通过查询窗口快速运行它。
最佳答案
我终于创建了这个辅助函数来构建可复制的查询行:
<cffunction name="limnSQLDump" output="no" access="public" returntype="string">
<cfargument name="sql" required="yes" type="string">
<cfargument name="params" required="yes" type="string">
<cfset var arrParam = ListToArray(arguments.params, ' , ', false, true)> <!--- Arrayify Dat Param String --->
<cfset var sub = StructNew()>
<cfset var objParam = StructNew()>
<cfloop from="1" to="#ArrayLen(arrParam)#" index="i"> <!--- Loop through each param string --->
<cfset arrParam[i] = REReplace(arrParam[i], '\(param \d+\) = \[([^\]]+)\]', '\1', 'all')> <!--- Scoop out the meat --->
<cfset sub = REFind("([^=, ]+)='([^']*)'", arrParam[i], 1, true)> <!--- Prep For Surgery --->
<cfset objParam = StructNew()> <!--- Preheat oven --->
<cfloop condition="#sub.pos[1]#"> <!--- Surgically get Key/Value --->
<cfset objParam[Mid(arrParam[i], sub.pos[2], sub.len[2])] = Mid(arrParam[i], sub.pos[3], sub.len[3])>
<cfset sub = REFind("([^=, ]+)='([^']*)'", arrParam[i], sub.pos[1]+sub.len[1], true)>
</cfloop>
<!--- Serve (Feeds 3) --->
<cfset sql = REReplace(sql, '\(param '&i&'\)', (objParam.class NEQ 'java.lang.Integer' ? "'"&objParam.value&"'" : objParam.value))>
</cfloop>
<cfreturn sql>
</cffunction>
任何反馈都将不胜感激,因为在我解决这个问题之前,我自己经历了无数不同的路线(从具体到抽象,然后再返回)。最后,我决定将整个参数字符串分解为一个数组(毕竟基本上是一个数组),正则表达式精确的参数并用它替换整个字符串,然后循环遍历参数并使对象等效,以便在对 SQL 字符串进行替换时,可以使用 REReplace 清楚地引用它。
我个人希望能够做类似 <cfset arrParam[i] = Evaluate("{"&arrParam[i])&"}">
的事情考虑到,除了括号之外,参数内容基本上是一个内联对象。
关于sql-server - 可复制的 Coldfusion SQL 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18133942/