当查询列是 cfqueryparam 变量时从 cfquery 获取单个输出

Getting a single output from cfquery when query column is cfqueryparam variable

我正在使用 ColdFusion 并尝试创建一个函数来获取特定帐户中特定列的值(每个帐户都是自己的 record/row)。

这样的函数工作正常:

<cffunction name="getColumnValueFromAccount" access="public" returntype="string" >
    <cfargument name="accountName" type="string" required="yes" />

    <cfquery name="getColumn" datasource="mydatasource">
        <!--- Note that the line below is 'hard-coded.' --->
        SELECT role_ExampleSystem
        FROM table_name
        WHERE (accountName = <cfqueryparam cfsqltype="cf_sql_varchar" maxlength="50" value='#accountName#'>)
    </cfquery>

    <!--- It's easy to return the column value when you know what its name was. --->
    <cfreturn getColumn.role_ExampleSystem > 

</cffunction>

但我真正想要的是一个函数,它允许我指定要读取的列名,并消除了制作一堆几乎相同的 CF 函数的需要,这些函数只是具有不同的硬编码 SELECT 范围。我认为它应该看起来像这样,但我在实际读取我认为应该返回的单个字符串时遇到了问题。

<cffunction name="getColumnValueFromAccount" access="public" returntype="string" >
    <cfargument name="accountName" type="string" required="yes" />
    <!--- Trying to accept a column name as an argument --->
    <cfargument name="columnName" type="string" required="yes" />

    <cfquery name="getColumn" datasource="mydatasource">
        <!--- I'm trying to use cfqueryparam to add specify the column name to select. --->
        SELECT <cfqueryparam cfsqltype="cf_sql_varchar" maxlength="50" value='#columnName#'>
        FROM table_name
        WHERE (accountName = <cfqueryparam cfsqltype="cf_sql_varchar" maxlength="50" value='#accountName#'>)
    </cfquery>

    <!--- This line doesn't work. --->
    <cfreturn getColumn[#columnName#] >

</cffunction>

我认为您可以在 getColumn[#columnName#]getColumn[columnName] 等括号符号中使用变量,因为有人在 comment 中提到过它。但是当我自己尝试使用变量时,它并没有按预期工作。我收到此错误:

The value returned from the getColumnValueFromAccount function is not of type string. If the component name is specified as a return type, it is possible that either a definition file for the component cannot be found or is not accessible.

知道当我想获得 cfquery 的单一结果时应该采取什么途径,但我没有在查询的 SELECT 部分使用硬编码的列名吗?通常这个过程很简单,但是当你的列名是一个变量时,事情似乎有点不同。

查询是一种数组结构,如查询名称[键][1]。

它在第一个实例中工作是因为向后兼容。从一开始,您可以执行 queryname.columnname 并且 CF 将输出该列查询的第一行。一旦你切换到对象语法,它就不再那样工作了。

在您的 cfreturn 中试试这个:

getColumn[columnName][1]

注意 - 在 cfreturn 示例中不需要井号。

我的解决方案:

根据 Leigh 的建议,我不能以我尝试使用它的方式使用 cfqueryparam,而 Mark A Kruger 的 我能够修改我的代码并让它工作.现在看起来像这样:

<cffunction name="getColumnValueFromAccount" access="public" returntype="string" >
    <cfargument name="accountName" type="string" required="yes" />
    <cfargument name="columnName" type="string" required="yes" />

    <cfquery name="getColumn" datasource="mydatasource">
        SELECT #columnName#
        FROM table_name
        WHERE (accountName = <cfqueryparam cfsqltype="cf_sql_varchar" maxlength="50" value='#accountName#'>)
    </cfquery>

    <cfreturn getColumn[columnName][1] >

</cffunction>

它现在正确地 return 指定系统中的帐户角色,即如果帐户 accountNameExampleSystem 中的 admin 并且我传入 role_ExampleSystem 作为 ColumnName 的函数,函数将 return admin 如预期的那样。

警告:如果使用不当,我的解决方案可能会带来 SQL 注入风险!

像这样在 SQL 语句中使用 ColdFusion 变量不会提供任何保护免受 SQL 注入,因此这将是一个 非常糟糕的主意 允许用户在此处输入用于 columnName 的数据。在我的例子中,这个函数只会被我编写的其他服务器端函数调用,并且用于 columnName 的数据将在服务器端函数中进行硬编码。另一方面,accountName 是用户指定的,因此它位于 cfqueryparam.

中很重要

另一种更安全的解决方案:

Mark A Kruger 只 select 您可能需要的每一专栏,然后只阅读您真正感兴趣的专栏,这可能是一个更好的主意。这看起来很不错主意。毕竟,获取记录的每个(相关)列不太可能是比我的单列示例大得多的数据库调用——除非您的数据库有包含大量列的大量记录。你也可以这样做,作为一个附带的好处,你不必担心 SQL 在 cfquery 中使用常规冷聚变 #variable# 的注射可能会打开你最多。

看了大家的回答和评论,很有启发。希望这个问题及其答案能帮助其他有兴趣在 ColdFusion 中做类似事情的人!