3

我是 ColdFusion 的新手,刚开始学习 Ajax。我的问题是,我在网上找到了一些很酷的代码来实现两个下拉菜单,第二个在哪里取决于从第一个中选择的内容。但目标是从选择查询中提取下拉列表中的所有值。

我正在使用我刚刚了解的绑定功能。第一次下拉中的所有内容都正确拉动。但问题是第二个。我从 AJAX 记录器得到的错误是"Error invoking: Error Executing Database Query"任何建议将不胜感激。也提前感谢您的帮助。

选择.cfc

<cfcomponent output="false">

    <!--- Get array of Catagory Description types --->
    <cffunction name="cat_description" access="remote" returnType="array">

        <!--- Define variables --->
        <cfset var data="">
        <cfset var result=ArrayNew(2)>
        <cfset var i=0>

        <!--- Get data --->
        <cfquery name="getServiceCat" datasource="SOME_DATABASE">
            SELECT DISTINCT CAT_DESC
            FROM   service_table
            ORDER BY CAT_DESC
        </cfquery>

        <!--- Convert results to array---> 
        <cfloop index="i" from="1" to="#getServiceCat.recordcount#">
            <cfset result[i][1]=getServiceCat.CAT_DESC[i]>
            <cfset result[i][2]=getServiceCat.CAT_DESC[i]>
        </cfloop>

        <!--- And return it --->
        <cfreturn result>
    </cffunction>

    <!--- Get Service Type by Cat description type --->
    <cffunction name="getServiceType2" access="remote" returnType="array">
        <cfargument name="CAT_DESC" type="string" required="true">

        <!--- Define variables --->
        <cfset var data="">
        <cfset var result=ArrayNew(2)>
        <cfset var i=0>

        <!--- Get data --->
        <cfquery name="getServiceType2" datasource="SOME_DATABASE" dbtype="query">
            SELECT DISTINCT com_service_code, report_desc
            FROM   service_table
            WHERE  CAT_DESC = #ARGUMENTS.CAT_DESC# 
            ORDER BY report_desc
        </cfquery>
        </cfif>

        <!--- Convert results to array --->
        <cfloop index="i" from="1" to="#getServiceType2.recordcount#">
            <cfset result[i][1]=getServiceType2.com_service_code[i]>
            <cfset result[i][2]=getServiceType2.report_desc[i]>
        </cfloop>

        <!--- And return it --->
        <cfreturn result>
    </cffunction>

 </cfcomponent>

以上是处理所有查询的cfc。此解决方案的主要原因之一是表单中所需代码的简单性。

 ...
 <td>Select Category: <cfselect name="catdesc"
                                 bind="cfc:select.cat_description()"
                                 bindonload="true"/><br />
 </td>
 ...
 <td>Select Service:  <cfselect name="service"
                                bind="cfc:select.getServiceType2({catdesc})"
                                bindonload="false"/>
 </td>

我已经搜索了将近 2 天,试图找到查询错误的解决方案。我知道查询在 SQL 中工作,所以我相信这个问题与 AJAX 有关,并且没有正确实现第二次下拉的 WHERE 子句。

同样,任何建议或建议都会很棒。此外,如果您以另一种方式执行此解决方案,我也很乐意尝试。正如我所说,我对这种语言非常陌生。仅 2 周。

4

2 回答 2

5

测试 CFC 的

在将它们插入 ajax 之前,始终在 CF 中测试 cfc。您验证 cfc 可以正常工作之前,没有必要搞乱绑定,因为如果它不能在 CF 中工作,那么它也不能与 ajax 一起工作。唯一的区别是错误将更难找到。

正如其他人建议的那样,从小处着手。自行测试查询。然后继续使用<cfinvoke>或简单地从浏览器中使用测试值来测试 CFC,例如:

http://yourserver/path/to/select.cfc?method=getServiceType2&cat_desc= 
http://yourserver/path/to/select.cfc?method=getServiceType2&cat_desc=someValue

错误

关于错误,我们需要查看完整的错误消息以提供更具体的建议。但是,查看查询/代码一些可能的原因是:

  1. CAT_DESC是一个 varchar 列,在这种情况下,您的参数必须用单引号引起来。否则数据库会认为参数值是对象名(表或列)。

    WHERE CAT_DESC = '#ARGUMENTS.CAT_DESC#' 
    
  2. .. ORCAT_DESC是数字列,但您的参数为空。这将导致无效的 sql 语句。您需要确保将有效数字传递到查询中(或者您可以在参数为空时跳过 WHERE 子句,具体取决于所需的结果)。一种常见的方法是使用该val()函数将空字符串和其他非数字值转换为零,即:

    WHERE CAT_DESC = #val(ARGUMENTS.CAT_DESC)#

  3. </cfif>在第二个查询之后,您似乎也有一个流浪者。(假设它不是复制/粘贴错误)

  4. 另一件事是,您的第二个查询同时指定了datasourceand dbtype。这两个属性是互斥的。两者都可能会导致语法错误(我没有尝试过)。无论哪种方式,您都应该只使用其中一个(最有可能datasource)。

SQL 注入

也就是说 - 上面的查询容易受到 sql 注入的影响。您应该始终使用<cfqueryparam>所有变量查询参数来防止 sql 注入。它还有其他好处(性能、数据类型检查等)。但是 sql 注入保护是 Web 应用程序中最关键的。

<!--- substitute the correct type for your db column --->
WHERE CAT_DESC = <cfqueryparam value="#ARGUMENTS.CAT_DESC#" 
                         cfsqltype="cf_sql_varchar">

改进

从 CF8.0.1+ 开始,cfselect可以绑定到查询对象(不仅仅是数组)。因此,无需构建数组,只需从函数返回原始查询。

    <cffunction name="getServiceType2" access="remote" returnType="query">
        <cfargument name="CAT_DESC" ....>

        <cfset var data="">

        <cfquery name="data" ..> 
           SELECT TheQueryColumnToDisplay, TheQueryColumnUsedForListValue
           FROM  ... 
           WHERE ... 
        </cfquery>

       <cfreturn data>
    </cffunction>

然后指定用于displayvalue属性的列:

    <cfselect name="service" 
              bind="cfc:select.getServiceType2({catdesc})"
              display="TheQueryColumnToDisplay"
              value="TheQueryColumnUsedForListValue" ...>
于 2013-01-25T20:54:32.630 回答
1

我的建议是一次做一件事。针对您的具体情况,

首先,让您的查询使用 cfquery 标记。

其次,让它在一个函数中工作,你将参数传递给函数。

接下来,将函数放在 cfc 中,并使用或通过创建对象并调用函数从 cfc 页面调用它。

最后做绑定。

这种方法将使错误更加明显,以便您可以对它们做一些事情。

其他意见

  1. 使用查询参数。
  2. 尝试将 id 字段而不是文本描述传递给您的查询
于 2013-01-25T18:23:31.347 回答