0

我正在尝试遍历 tableList 并为每个表运行查询以获取每个表的计数。并非所有代码都包含在内,但问题在于 cfqueryparam。当我现在运行此代码时,错误显示“INVALID TABLE NAME”。这是我现在正在尝试的:

<cfloop list="#tableList#" index="t">
<cfquery name="getcount" datasource="erisnetselect">
SELECT COUNT(*) FROM <cfqueryparam value='AUDITOR.#t#' sqltype="VARCHAR">
</cfquery>

问题特别是这一行:

SELECT COUNT(*) FROM <cfqueryparam value='AUDITOR.#t#' sqltype="VARCHAR">

我也试过:

SELECT COUNT(*) FROM AUDITOR.<cfqueryparam value='#t#' sqltype="VARCHAR">

但我得到同样的错误。

我认为可能有一种方法可以在这些表名到达查询之前对其进行清理,但我不知道该怎么做。如果您需要所有代码,我可以提供更多,但这是一个巨大的页面。

4

1 回答 1

3

cfqueryparam是准备好的语句的值占位符。您不能将值占位符用于表名或列名,因为准备好的语句要求查询在放入任何值之前是完整且有效的。准备好的语句的设计目标之一是通过分离查询和值来防止恶意注入。分离是通过首先发送不带实际值的查询(值占位符通常用问号表示?),让 SQL 服务器解析并理解它(查询解释器)然后等待数据放入准备好的值槽来实现的。这也带来了性能优势,因为 SQL 服务器可以重用已经解释过的查询,同时发送带有查询和值的纯字符串语句总是需要再次解析它。

要解决您的问题,您必须使用适当的命令生成器/引用器(取决于 SQL 供应商,检查您的 JDBC 驱动程序)或手动验证名称来清理表名。

如果你必须使用手动方式,你应该保守,只允许万无一失的字符,如字母、数字、下划线和连字符。考虑一下:

<cfloop list="#tableList#" index="t">

    <!--- make sure the table name only consists of alphabetic letters, digits, underscores and hyphens --->
    <cfif not reFind("^[a-zA-Z0-9_-]+$", t)>
        <cfthrow message='The specified table name, which is "#t#", contains illegal characters.'>
    </cfif>

    <cfquery name="getcount" datasource="erisnetselect">
        SELECT COUNT(*) FROM AUDITOR.#t#
    </cfquery>

    ...
于 2020-02-18T21:37:21.163 回答