2

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

<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>

cf_datatables_records定义标签(子)是一个子查询/记录集,将在cf_datatables自定义标签(父)中使用。这将是执行上述操作时的 SQL 结果:

SELECT
    SQL_CALC_FOUND_ROWS *

FROM (

        SELECT
            `someColumn1`,
            `someColumn2`

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

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

        LIMIT
            10

) AS `base`

UNION (...)

WHERE ... GROUP BY ... ORDER BY ... LIMIT ... etc. (depends on the provided parameters)

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

Context validation error for tag cfqueryparam. The tag must be nested inside a cfquery tag.

如果我省略它确实有效,cfqueryparam但这显然是不可接受的。解析查询参数也是如此。

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

4

3 回答 3

0

好的,我刚刚发现我可以在 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>

两者包括动态补充选择。

内容datatables-processing-pre.cfm

SELECT
    SQL_CALC_FOUND_ROWS *

FROM (

内容datatables-processing-post.cfm

) 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>

...
于 2014-10-30T16:24:08.610 回答
0

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

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

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

https://github.com/sebtools/Neptune

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

总而言之,它可以完成,但预计要花一些时间。

由于 Mark Kruger(我尊重并钦佩他)提出这样的想法,即此类标签只会为您带来开销,因此我将补充说,此类自定义标签可以带来真正的好处。我看到的标签包括在由于数据库连接断开而失败的情况下重试整个查询调用(可能是对不同的数据库)的能力。

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

于 2014-10-30T20:30:41.937 回答
-1

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

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

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

同意,这并不比使用 cfqueryparam 更好,但是根据用例可能没问题。

于 2014-11-02T00:15:13.280 回答