如果我是一个运行在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>
说的extern包括富,酒吧和foobar的。 它是允许的,更好的写:
extern.foo;
extern.bar;
extern.foobar;
因为我正在通过一个页面,往往会发现这些“裸”变量有点混乱遵循:
foo;
bar;
foobar;
有很多的范围和适当的作用域的信息,但我还没有找到查询输出任何东西。
感谢澄清!
有些人会告诉你,这是很好的习惯用法总是范围,因为它让你作出错误的范围界定它是非常重要的。
在个人的看法,我喜欢用CFOUTPUT与查询并不必范围的方法 - 它是“WITH”在其他语言中的等价物。 由于查询总是会前形式和URL范围查询驱动CFOUTPUT标签内的评价我没有看到过留下的范围在实例中的任何问题。 请记住,在氟氯化碳“论据”与局部范围内都将是抢占-但是这不是一个查询驱动CFOUTPUT最好的地方-它被设计(巧妙地设计)为方便显示 。
但再次..别人会告诉你不同的(有一些激情,以及:)。
有这个,如果你不完全范围的变量范围的问题。
你会得到人们说你不会遇到足以证明额外的输入问题,但是和ColdFusion的,因为有它的不干燥, 范围评估顺序 ,如果你有,你想工作不管上下文代码是必需的。
通过下面的“查询循环”我的意思是cfloop
或cfoutput
与query
参数。
所以,你可以使用#columnname#
查询循环中。
你可以 #queryName.columnName#
内部或查询循环外。
你应该 #cfScope.queryName.columnName#
在所有情况下。
下面是事情出错的例子。 希望你永远不会有应对这样的代码,但它用于指出与ColdFusion的广泛问题范围的评估 。
<cfset testcfc = new Test().scopeTest()>
同
<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>
输出的结果是这不是从一个查询; 参数范围。 相反的是范围评估文档 ,和别人希望你相信。
正如其他人建议你可以改变输出线读<cfoutput>#Query.xlocal#</cfoutput>
但这并没有帮助。 相反,你被告知列不存在。 其改为<cfoutput>#Query.xarguments#</cfoutput>
将表明,它是使用Arguments
的版本Query
代替的local
或Variables
。
因此,如何:
<cfloop query="local.Query">
<cfoutput>#xlocal#</cfoutput>
</cfloop>
不。 还没想要的结果。 好了,如何添加查询名称的输出:
<cfloop query="local.Query">
<cfoutput>#Query.xlocal#</cfoutput>
</cfloop>
不。 还没所期望的结果。 如果你想确保你得到你有充分的范围是所有正确的结果。
<cfloop query="local.Query">
<cfoutput>#local.Query.xlocal#</cfoutput>
</cfloop>
这是方式更打字比任何人都想做的事,但如果你想确保没有任何讨厌的错误潜伏在你的代码是必需的。
我那些家伙谁都会告诉你,你应该范围的一切之一。 阅读自己的代码和其他代码,当它真的会让人有帮助。 我说:“毫无疑问,范围吧!”
下面是我如何做一般的查询,然后将结果输出的例子。
<cfscript>
Q = MyCFC.getCustomers();
if (! isQuery(Q) || Q.RecordCount == 0) {
writeOutput("No records found.");
} else {
for (i = 1; i lte Q.RecordCount; i++) {
VARIABLES.Customer = "#Q.FirstName[i]# #Q.LastName[i]#";
writeOutput(VARIABLES.Customer);
writeOutput("<br>");
}
}
</cfscript>
这是当它是必要的,当它是有价值的范围内的大讨论。
我会扔我的两个便士总是作用域的方向如果只是清晰度或缩小CFC的。 如果你有,无功Q =“”; 然后刚才提到q让您拥有一个本地范围的变量,如果你是懒惰的,并相信DRY包括作用域。
我不能告诉你的系统,我已经上了作用域如此糟糕,我不得不调试找出从那里什么来工作的页数。 特别是在复杂的报表,其中分组依据和次要数据是涉及; 它可以变得非常混乱。
一个忌讳是我见过的人使用技巧(故意或不),他们默认设置了一个param没有它会被分配到“变量”的范围,然后在他们的代码,他们会混杂形式和URL作用域,期待一个覆盖另外,和/或变量范围的值与没有范围,使输出将始终找不到值的缺省变量版本....当然,因为他们预期...啊代码不自重!
即使在一个CFQUERY / CFOUTPUT / CFLOOP与查询属性我建议作用域的清晰度。 此外,没有任何理由cfouput / CFLOOP不能在CFC /对象内部使用。
当然,也有很简单的输出,我可能放下“变量”范围之外时,在CFC目前尚未有其他范围内的页面混合非常基本的输出的场合,但我发现,这是罕见的。
对我来说,这只是简单的永远是正确划定范围的值的习惯。
即:
<cfprocresult name="Local.qExtern">
接着:
<cfoutput query='Local.qExtern'>
#Local.qExtern.szNameFirst#
#Local.qExtern.szNameLast#
</cfoutput>
总之,我断定3个原因除了对在最简单的情况下始终作用域倾斜:
CLARITY与保养
清晰度下一个程序员,自己半年后看一些代码比你节省不划定范围的几个按键更有价值。 如果你的代码是不是简单地倾倒的查询,而循环它和其他逻辑或变量/值成为你的输出穿插更复杂的情况尤其如此。
BLEEDING&LOCKING
此外,在CFC和使用不当作用域瓦尔时,你肯定跑变量出血的风险尤其是默认的范围要被保护的范围,而不是局部范围。 我也看到严重的性能下降时,多种方法*和/或特殊方法访问公共(保护)的范围,需要从等待方法/请求也试图使用该名称空间(锁定该变量哦,是啊,流血的)。
速度:
最后,我会怀疑,在JS和其他语言,一个作用域变量更快地比未范围变量CF发动机即使在默认范围内找到。
*脚注:我想澄清这种情况出现的情况。 范围的不良单身(工具类缓存到应用程序,例如)是最有可能的情况下导致意外的保护范围变量锁定这会降低你的系统/请求队列。 使用相同的请求中的相同变量的多个方法是(主叫在同一对象的其它辅助方法递归函数,方法),其中一个未varred变量像本地范围的变量治疗的病例,并且将典型地导致出血(非预期的再利用/造成意外的结果相同的变量)的操纵。