我是否必须在Coldfusion中查询输出范围?

fre*_*ent 3 mysql coldfusion scope

如果我在Coldfusion中运行数据库查询/存储过程,那么引用查询返回的字段的正确方法是什么?

<cfstoredproc procedure="proc_select_extern" datasource="stokkers">
    <cfprocparam type="in" value="#Session.Extern#" cfsqltype="cf_sql_varchar" maxlength="13">
    <cfprocresult name="extern">
</cfstoredproc>
<cfoutput query="extern">
   <cfset variables.some = extern.foo>
   OR 
   <cfset variables.some = foo>
</cfouput>
Run Code Online (Sandbox Code Playgroud)

extern包括foo,bar和foobar.是否允许并且写得更好:

 extern.foo;
 extern.bar;
 extern.foobar;
Run Code Online (Sandbox Code Playgroud)

因为我正在浏览一个页面并经常发现这些"裸"变量有点令人困惑:

 foo;
 bar;
 foobar;
Run Code Online (Sandbox Code Playgroud)

关于范围和正确的范围有很多信息,但我没有在查询输出上找到任何东西.

谢谢你的澄清!

Mar*_*ger 7

有些人会告诉你,始终保持范围是一种很好的习惯做法,因为它可以防止你在确定重要范围时出现范围错误.

在个人观点中,我喜欢将cfoutput与查询一起使用的方法,而不是范围 - 它在其他语言中等同于"WITH".由于查询将始终在查询驱动的cfoutput标记内的表单和url作用域之前进行评估,因此我没有看到在该实例中省略该作用域的任何问题.请记住,在CFC中,"参数"和本地范围都是抢占式的 - 但这不是查询驱动的cfoutput的最佳位置 - 设计(设计合理)以方便显示.

但是,再一次..其他人会告诉你不同的(也有一些激情:).

  • 谢谢:-)所以我想我会对它充满热情和范围. (2认同)

nos*_*leg 5

如果您没有完全确定变量范围,则存在范围问题.

你会让人们说你不会遇到足以证明额外输入的问题,而且它不是DRY,但是因为ColdFusion有一个范围评估顺序,如果你有代码你想要工作而不管上下文.

通过下面的'查询循环',我的意思是一个cfloopcfoutput一个query参数.

所以,你可以使用#columnname#一个查询循环中.

可以 #queryName.columnName#在查询循环内部或外部.

应该 #cfScope.queryName.columnName#在所有情况下.

这是一个出错的例子.希望您永远不必处理这样的代码,但它可以指出ColdFusion广泛的范围评估问题.

<cfset testcfc = new Test().scopeTest()>
Run Code Online (Sandbox Code Playgroud)

<cfcomponent output="false">

    <cffunction name="scopeTest" access="public" output="true" returntype="void">
        <cfargument name="Query" type="query" required="false" default="#QueryNew("xarguments")#">
        <cfargument name="xlocal" type="string" required="false" default="This is not from a query; Arguments scope.">

        <cfset QueryAddRow(Arguments.Query, 1)>
        <cfset Arguments.Query["xarguments"][1] = "this is the arguments scope query">
        <cfset local.Query = QueryNew("xlocal")>
        <cfset QueryAddRow(local.Query, 1)>
        <cfset local.Query["xlocal"][1] = "this is the local scope query">
        <cfset Variables.Query = QueryNew("xVariables")>
        <cfset QueryAddRow(Variables.Query, 1)>
        <cfset Variables.Query["xVariables"][1] = "this is the variables scope query">

        <cfset local.xlocal = "This is not from a query; local scope.">

        <cfloop query="Query">
            <cfoutput>#xlocal#</cfoutput>
        </cfloop>

        <cfdump var="#Arguments#" label="Arguments">
        <cfdump var="#local#" label="local">
        <cfdump var="#variables#" label="Variables">
        <cfabort>
    </cffunction>

</cfcomponent>
Run Code Online (Sandbox Code Playgroud)

输出的结果是这不是来自查询; 参数范围.范围评估文档相反,以及其他人会相信什么.

正如其他人所建议的那样,您可以将输出行更改为读取,<cfoutput>#Query.xlocal#</cfoutput>但这也无济于事.相反,你被告知该列不存在.将其更改为<cfoutput>#Query.xarguments#</cfoutput>将显示它使用的是Arguments版本Query而不是localVariables.

那怎么样:

        <cfloop query="local.Query">
            <cfoutput>#xlocal#</cfoutput>
        </cfloop>
Run Code Online (Sandbox Code Playgroud)

不.仍然不是理想的结果.好的,那么如何将查询名称添加到输出中:

        <cfloop query="local.Query">
            <cfoutput>#Query.xlocal#</cfoutput>
        </cfloop>
Run Code Online (Sandbox Code Playgroud)

不.仍然不是理想的结果.如果你想确保得到正确的结果,你必须完全适应它.

        <cfloop query="local.Query">
            <cfoutput>#local.Query.xlocal#</cfoutput>
        </cfloop>
Run Code Online (Sandbox Code Playgroud)

这种方式比任何人想做的都要多,但如果你想确保代码中没有任何讨厌的错误,则需要输入.