Coldfusion 是否将cfqueryparam与自定义标记一起使用?用自定义标记嵌套本机标记

Coldfusion 是否将cfqueryparam与自定义标记一起使用?用自定义标记嵌套本机标记,coldfusion,nested,cfquery,custom-tags,cfqueryparam,Coldfusion,Nested,Cfquery,Custom Tags,Cfqueryparam,我基本上想允许这样的事情: <cf_datatables datasource="#someDS#"> <cf_datatables_records> SELECT `someColumn1`, `someColumn2` FROM `#someDB#`.`#someT#` WHERE `someColumn1`

我基本上想允许这样的事情:

<cf_datatables datasource="#someDS#">

    <cf_datatables_records>

        SELECT
            `someColumn1`,
            `someColumn2`

        FROM
            `#someDB#`.`#someT#`

        WHERE
            `someColumn1` = <cfqueryparam value="#someValue#"  cfSqlType="CF_SQL_INTEGER">

        LIMIT
            10

    </cf_datatables_records>

</cf_datatables>
不幸的是,ColdFusion在将
cfqueryparam
标记传递给自定义标记之前会对其进行解析,从而导致:

标记cfqueryparam的上下文验证错误。标记必须嵌套在cfquery标记中。

如果我省略了
cfqueryparam
,它确实可以工作,但这显然是不可接受的。解析queryparam也是如此


知道如何解决这个问题吗?

好的,我刚刚发现我可以在cfquery中包含SQL指令,而不必处理本机标记问题

<cfquery datasource="#someDS#">

    <!--- count possible records --->
    <cfmodule dtArguments="#dtController.params#" template="datatables-processing-pre.cfm">

        <!--- select records for the desired entity --->
        SELECT
            `someColumn1`,
            `someColumn2`

        FROM
            `#someDB#`.`#someT#`

        WHERE
            `someColumn1` = <cfqueryparam value="#someValue#"  cfSqlType="CF_SQL_INTEGER">

        LIMIT
            10

    <!--- filter, order and paginate records --->
    <cfmodule dtArguments="#dtController.params#" template="datatables-processing-post.cfm">

</cfquery>
数据表处理post.cfm的内容

SELECT
    SQL_CALC_FOUND_ROWS *

FROM (
) AS 'base'

WHERE
    <cfswitch ...>
        <defaultcase>
            `someColumn3` > <cfqueryparam value="#someOtherValue#"  cfSqlType="CF_SQL_INTEGER">
        </defaultcase>
    </cfswitch>

    <cfif ...>
        AND `someColumn4` LIKE <cfqueryparam value="#anotherValue#%"  cfSqlType="CF_SQL_VARCHAR">
    </cfif>

ORDER BY
    <cfswitch ...>
        ...
    </cfswitch>

...
)作为“基本”
哪里
`someColumn3`>
还有像这样的
订购人
...
...

好的,我刚刚发现我可以在cfquery中包含SQL指令,而不必处理本机标记问题

<cfquery datasource="#someDS#">

    <!--- count possible records --->
    <cfmodule dtArguments="#dtController.params#" template="datatables-processing-pre.cfm">

        <!--- select records for the desired entity --->
        SELECT
            `someColumn1`,
            `someColumn2`

        FROM
            `#someDB#`.`#someT#`

        WHERE
            `someColumn1` = <cfqueryparam value="#someValue#"  cfSqlType="CF_SQL_INTEGER">

        LIMIT
            10

    <!--- filter, order and paginate records --->
    <cfmodule dtArguments="#dtController.params#" template="datatables-processing-post.cfm">

</cfquery>
数据表处理post.cfm的内容

SELECT
    SQL_CALC_FOUND_ROWS *

FROM (
) AS 'base'

WHERE
    <cfswitch ...>
        <defaultcase>
            `someColumn3` > <cfqueryparam value="#someOtherValue#"  cfSqlType="CF_SQL_INTEGER">
        </defaultcase>
    </cfswitch>

    <cfif ...>
        AND `someColumn4` LIKE <cfqueryparam value="#anotherValue#%"  cfSqlType="CF_SQL_VARCHAR">
    </cfif>

ORDER BY
    <cfswitch ...>
        ...
    </cfswitch>

...
)作为“基本”
哪里
`someColumn3`>
还有像这样的
订购人
...
...

问题是可以解决的,但可能不像您希望的那么容易

您必须创建一个标记(或类似的标记)来替换标记。其中每一个都必须输出一个字符串,您可以使用该字符串(可能与标记提供给其父标记的某些数据结合使用)稍后在父标记的结束模式下通过一些循环和字符串替换来重新创建cfqueryparam标记

如果您想在工作中看到它的示例,请查看我的Neptune框架的自定义标记中的cf_DMQuery和cf_DMSQL标记

您可以在存储库的“CustomTags”文件夹中找到它们。问题的症结在于DMUdfs.cfm中的convertSQLArray函数。它利用DataMgr.cfc中的功能来处理高度动态的SQL代码

总而言之,这是可以做到的,但我们希望在这上面花些时间

既然马克·克鲁格(我尊敬和敬佩他)认为这样的标签只会给你带来额外的开销,那么我要补充的是,这样的定制标签可以带来真正的好处。我见过一些标签,其中包括在由于数据库连接关闭而出现故障时重试整个查询调用(可能是对另一个数据库)的功能


我使用它们是为了在多个不同的查询中使用复杂的SQL(包括cfqueryparams)。我获得了在SQL中执行复杂逻辑的速度优势,而无需代码复制成本。然而,很难给出这样的例子,因为你的情况必须达到一定的复杂程度才能得到回报(这使得很难给出一个简洁的例子)。

问题是可以解决的,但可能不像你希望的那么容易

您必须创建一个标记(或类似的标记)来替换标记。其中每一个都必须输出一个字符串,您可以使用该字符串(可能与标记提供给其父标记的某些数据结合使用)稍后在父标记的结束模式下通过一些循环和字符串替换来重新创建cfqueryparam标记

如果您想在工作中看到它的示例,请查看我的Neptune框架的自定义标记中的cf_DMQuery和cf_DMSQL标记

您可以在存储库的“CustomTags”文件夹中找到它们。问题的症结在于DMUdfs.cfm中的convertSQLArray函数。它利用DataMgr.cfc中的功能来处理高度动态的SQL代码

总而言之,这是可以做到的,但我们希望在这上面花些时间

既然马克·克鲁格(我尊敬和敬佩他)认为这样的标签只会给你带来额外的开销,那么我要补充的是,这样的定制标签可以带来真正的好处。我见过一些标签,其中包括在由于数据库连接关闭而出现故障时重试整个查询调用(可能是对另一个数据库)的功能


我使用它们是为了在多个不同的查询中使用复杂的SQL(包括cfqueryparams)。我获得了在SQL中执行复杂逻辑的速度优势,而无需代码复制成本。但是,很难给出这样的示例,因为您的情况必须达到一定的复杂性才能得到回报(这使得很难给出一个简洁的示例)。

为什么不在执行查询之前添加一个检查,看看值的类型是否正确,而不是cfqueryparam

<cfif NOT IsNumeric(somevalue)>
  <cfabort>
</cfif>

编辑:整数也有类型检查:IsValid(“integer”,somevalue)


同意,这并不比使用cfqueryparam好,但是根据用例的不同,它可能会更好。

为什么不在执行查询之前添加一个检查,看看值是否是正确的类型,而不是cfqueryparam

<cfif NOT IsNumeric(somevalue)>
  <cfabort>
</cfif>

编辑:整数也有类型检查:IsValid(“integer”,somevalue)


同意,这并不比使用cfqueryparam好,但是根据用例的不同,它可能会更好。

不确定为什么会存在这种自定义标记。这就像是对cfquery的重写,效果非常好。我认为,除非重写datatables自定义标记,在最终将其放入cfquery标记时包含cfqueryparam,否则无法修复此问题。除了额外的解析开销外,使用此自定义标记不会带来任何好处。哎呀,这在标记中是不可能的。可能使用cfquery的cfscript版本。然而,我也不确定我是否看到了它的价值。用例是什么?旁注,根据
#foo2#
#foo3#
的源代码,您仍然可以将数据库公开给sql注入。目的是简化数据的准备方式。我希望我们的初级开发人员只关心记录,而不是动态筛选、确定