查询不能按列名索引,但列不应存在

时间:2015-02-23 17:11:31

标签: coldfusion coldfusion-9

所以我经常遇到这个错误,主要是由机器人引起的:

java.lang.IllegalArgumentException: 
  [Table (rows 0 columns ID, BOOKID, EDITIONID, EDITIONNAME, PRACTICEAREALINK, PUBLISHED): 
  ...REALINK: coldfusion.sql.QueryColumn@2c12f137] 
  [PUBLISHED: coldfusion.sql.QueryColumn@f9a687c] ] is not indexable by webtypeid

然而,它所引用的列无法在它试图引用的查询中找到。

所以我们这里有3个文件,一个index.cfm,一个Business.cfc和一个DAO.cfc。在业务中代码如下:

<cfcomponent extends="_lbr._core.NativeBusiness">
  <cffunction name="init" access="public" output="false" returntype="_lbr._who._publication._Edition.EditionBusiness" hint="Pseudo-constructor">
    <cfargument name="oEditionDAO"          type="_lbr._who._publication._Edition.EditionDAO"           required="true">
    <cfscript>
        super.init(argumentCollection=arguments);

        variables.oEditionDAO       = arguments.oEditionDAO;

        return this;
    </cfscript>
  </cffunction>

  <cffunction name="getEditionByPracticeArea" returntype="query" access="public">
    <cfargument name="nEditionID" type="numeric" required="false">
    <cfargument name="nPraciceAreaID" type="numeric" required="false">
    <cfargument name="bPublished" type="boolean" required="false">
    <cfscript>
        return variables.oEditionDAO.getEditionByPracticeArea(argumentCollection=arguments);
    </cfscript>
  </cffunction>

  <cffunction name="getEditionsByPracticeArea" returntype="query" access="public">
    <cfargument name="nPracticeAreaID" type="numeric" required="false">
    <cfargument name="bPracticeAreaLink" type="boolean" required="false">
    <cfargument name="bPublished" type="boolean" required="false">
    <cfargument name="lstFields" type="string" required="false">
    <cfscript>
        return variables.oEditionDAO.getEditionsByPracticeArea(argumentCollection=arguments);
    </cfscript>
  </cffunction>

  <cffunction name="getTypesByPracticeArea" returntype="query" access="public">
    <cfargument name="nPracticeAreaID" type="numeric" required="false">
    <cfargument name="nEditionID" type="numeric" required="false">
    <cfscript>
        return variables.oEditionDAO.getTypesByPracticeArea(argumentCollection=arguments);
    </cfscript>
  </cffunction>

</cfcomponent>

没有什么特别不寻常的。

DAO看起来像

<cfcomponent extends="_lbr._core.NativeDAO">
  <cffunction name="init" access="public" output="false" returntype="_lbr._who._Publication._Edition.EditionDAO" hint="Pseudo-constructor">
    <cfargument name="sDSN" type="string" required="true" hint="The datasource name to use to access the database through.">
    <cfargument name="oCFML"            type="_lbr._util._cfml.CFML"    required="true" hint="The CFML object to use for scripting.">
    <cfscript>
        super.init(argumentCollection=arguments);
        variables.sDSN                  = arguments.sDSN;
        variables.oCFML                 = arguments.oCFML;
        variables.lstFields             = "p.publication_ID, p.publication_name, e.edition_id, e.edition_name, e.pub_year, e.pub_date";
        variables.lstSubEditionFields   = "id,bookid,editionid,editionname,practiceareaLink,published";
        return this;
    </cfscript>
  </cffunction>

  <cffunction name="getEditionByPracticeArea" returntype="query" access="public">
    <cfargument name="nEditionID" type="numeric" required="false">
    <cfargument name="nPraciceAreaID" type="numeric" required="false">
    <cfargument name="bPublished" type="boolean" required="false">
    <cfargument name="nStartRow" required="true" type="numeric" default="0">
    <cfargument name="nEndRow" required="true" type="numeric" default="1">
    <cfscript>
        return selectEditionsByPracticeArea(argumentCollection=arguments);
    </cfscript>
  </cffunction>

  <cffunction name="getEditionsByPracticeArea" returntype="query" access="public">
    <cfargument name="nPracticeAreaID" type="numeric" required="false">
    <cfargument name="bPracticeAreaLink" type="boolean" required="false">
    <cfargument name="bPublished" type="boolean" required="false">
    <cfargument name="lstFields" type="string" required="false">
    <cfscript>
        return selectEditionsByPracticeArea(argumentCollection=arguments);
    </cfscript>
  </cffunction>

  <cffunction name="selectEditionsByPracticeArea" returntype="query" access="public">
    <cfargument name="nStartRow" required="true" type="numeric" default="0">
    <cfargument name="nEndRow" required="true" type="numeric" default="100">
    <cfargument name="nEditionID" type="numeric" required="false" default="0">
    <cfargument name="nPracticeAreaID" type="numeric" required="false" default="0">
    <cfargument name="bPracticeAreaLink" type="boolean" required="false">
    <cfargument name="bPublished" type="boolean" required="false">
    <cfargument name="lstFields" type="string" default="#variables.lstSubEditionFields#" required="false">
    <cfquery name="qQuery" datasource="#variables.sDSN#">
        SELECT #arguments.lstFields#
          FROM tbl_who_subeditions
         WHERE 1
        <cfif arguments.nPracticeAreaID gt 0>
            AND bookid = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.nPracticeAreaID#">
        </cfif>
        <cfif arguments.nEditionID gt 0>
            AND editionID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.nEditionID#">
        </cfif>
        <cfif structKeyExists(arguments,"bPublished")>
            AND published = <cfqueryparam cfsqltype="cf_sql_bit" value="#arguments.bPublished#">
        </cfif>
        <cfif arguments.nPracticeAreaID gt 0 OR arguments.nEditionID gt 0>
            <cfif structKeyExists(arguments,"bPracticeAreaLink")>
                AND practiceareaLink = <cfqueryparam cfsqltype="cf_sql_tinyint" value="#arguments.bPracticeAreaLink#">
            </cfif>
        </cfif>
        LIMIT #arguments.nStartRow#,#arguments.nEndRow#
    </cfquery>
    <cfreturn qQuery>
  </cffunction>

  <cffunction name="getTypesByPracticeArea" returntype="query" access="public">
    <cfargument name="nPracticeAreaID" type="numeric" required="false">
    <cfargument name="nEditionID" type="numeric" required="false">
    <cfscript>
        return selectTypesByPracticeArea(argumentCollection=arguments);
    </cfscript>
  </cffunction>

  <cffunction name="selectTypesByPracticeArea" returntype="query" access="public">
    <cfargument name="nStartRow" required="true" type="numeric" default="0">
    <cfargument name="nEndRow" required="true" type="numeric" default="100">
    <cfargument name="nEditionID" type="numeric" required="false" default="0">
    <cfargument name="nPracticeAreaID" type="numeric" required="false" default="0">
    <cfargument name="lstFields" type="string" default="#variables.lstSubEditionFields#" required="false">
    <cfquery name="qQuery" datasource="#variables.sDSN#">
        SELECT distinct webtypeid, typename
          FROM tbl_who_webtype2practiceareas wp
          JOIN tbl_who_webtypes w ON wp.webtypeid = w.id
         WHERE 1
        <cfif arguments.nPracticeAreaID gt 0>
            AND bookid = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.nPracticeAreaID#">
        </cfif>
        <cfif arguments.nEditionID gt 0>
            AND editionid = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.nEditionID#">
        </cfif>
        LIMIT #arguments.nStartRow#,#arguments.nEndRow#
    </cfquery>
    <cfreturn qQuery>
  </cffunction>
</cfcomponent>

唯一不寻常的是selectTypesByPracticeArea有一个variables.lstSubEditionFields默认的lstFields,但由于它没有在该函数中使用,所以它不应该成为问题

所以index.cfm只有

variables.stArgs = {};
variables.stArgs.nPracticeAreaID  = request.parameters.nPublicationID;
variables.stArgs.nEditionID = request.parameters.nSubEdition;

variables.qTypes = application.stObj.oEditionBusiness.getTypesByPracticeArea(argumentCollection=variables.stArgs);

if(variables.qTypes["webtypeid"].IndexOf(JavaCast("int",2)) GTE 0 OR variables.qTypes["webtypeid"].IndexOf(JavaCast("int",3)) GTE 0){
  request.parameters.bHasTypes = true;
}

if语句发生错误。它应该只接收包含webtypeidtypename的查询,那么它认为它从哪里获得ID, BOOKID, EDITIONID, EDITIONNAME, PRACTICEAREALINK, PUBLISHED?我可以理解的是,它与lstfields混淆了......但这没有任何意义。

1 个答案:

答案 0 :(得分:3)

乍一看,我怀疑你没有使用var声明函数的qQuery本地,因此在执行这些方法时有时会被覆盖。如果您在CFQUERY标记之前尝试此操作,您可能会看到它消失:

<cfset var qQuery = "">

您也可以像local.qQuery

一样使用LOCAL范围