使用空值和列表查询
querying with nulls and lists
我有
QueryExecute(
SELECT *
FROM dbo.pages
WHERE ID IN ( :id )
...
,
{
id : { value = rc.id, cfsqltype : "cf_sql_integer, list : true }
}
几乎所有时间都有效。问题是 rc.id
可以为空。如果为空,则应匹配所有 ID。我对如何执行此操作感到困惑
这里有两种不同的选择。
1) 当变量不为空时,您可以操纵查询字符串仅包含 IN 语句。
您如何处理这件事实际上取决于查询的其余部分以及您希望如何执行此操作。
<cfset sqlstr = "SELECT * FROM dbo.pages" />
<cfif len(rc.id)>
<cfset sqlstr &= " WHERE ID IN ( :id )" />
</cfif>
您可以使用条件输出更干净地构建...
WHERE #len(rc.id) ? "ID IN ( :id )" : ""#
为了避免担心是否包含 WHERE/AND/OR,一个小技巧是包含一个始终通过(或在 ORing 的情况下永远不会通过)的子句
WHERE 1=1
#len(rc.id) ? "AND ID IN ( :id )" : ""#
AND ...
2)两次传参并在数据库中进行校验
SELECT *
FROM dbo.pages
WHERE (len(':id') = 0 OR ID IN ( :id ))
...
-- note: this may be problematic if CF is passing null when blank
或者只是长度
QueryExecute(
SELECT *
FROM dbo.pages
WHERE (:idlen > 0 OR ID IN ( :id ))
...
,
{
id : { value = rc.id, cfsqltype : "cf_sql_integer, list : true },
idlen : { value = len(rc.id), cfsqltype : "cf_sql_integer" }
}
这里我也给出了关于使 queryparam 有条件的示例代码。出于测试目的,我创建了一些默认参数和值
<cfparam name="id" default="1,2,3,4,5,6">
将查询详细信息设置为字符串并将其保存到另一个变量,如上面提到的@danRoberts。
<cfset MyQry = "SELECT * FROM pages ">
检查 rc.id 值是否为空。如果不是,请附加 IN
子句。
<cfif len(rc.id) >
<cfset MyQry &= " WHERE id IN ( :id ) ">
</cfif>
作为参考,我还添加了一些额外的运算符。
<cfset MyQry &= " limit 10 ">
接下来,基于new 运算符
创建一个新查询
<cfset qry = new Query( datasource ='yourDataSource' , sql = MyQry) >
之后,如果rc.id不为空
,则为:ID
添加queryParam
<cfif len(rc.id) >
<cfset qry.addParam( name="id", value="#rc.id#",cfsqltype="cf_sql_varchar",list='true') >
</cfif>
注意:使用IN
运算符时,需要设置
list='true' 查询参数。
然后你执行查询,如下所示
<cfset Result = qry.execute().getResult() >
<cfdump var="#Result#" />
带有queryParam的WHERE
子句只有在rc.ID包含一个值时才会执行。
我有
QueryExecute(
SELECT *
FROM dbo.pages
WHERE ID IN ( :id )
...
,
{
id : { value = rc.id, cfsqltype : "cf_sql_integer, list : true }
}
几乎所有时间都有效。问题是 rc.id
可以为空。如果为空,则应匹配所有 ID。我对如何执行此操作感到困惑
这里有两种不同的选择。
1) 当变量不为空时,您可以操纵查询字符串仅包含 IN 语句。
您如何处理这件事实际上取决于查询的其余部分以及您希望如何执行此操作。
<cfset sqlstr = "SELECT * FROM dbo.pages" />
<cfif len(rc.id)>
<cfset sqlstr &= " WHERE ID IN ( :id )" />
</cfif>
您可以使用条件输出更干净地构建...
WHERE #len(rc.id) ? "ID IN ( :id )" : ""#
为了避免担心是否包含 WHERE/AND/OR,一个小技巧是包含一个始终通过(或在 ORing 的情况下永远不会通过)的子句
WHERE 1=1
#len(rc.id) ? "AND ID IN ( :id )" : ""#
AND ...
2)两次传参并在数据库中进行校验
SELECT *
FROM dbo.pages
WHERE (len(':id') = 0 OR ID IN ( :id ))
...
-- note: this may be problematic if CF is passing null when blank
或者只是长度
QueryExecute(
SELECT *
FROM dbo.pages
WHERE (:idlen > 0 OR ID IN ( :id ))
...
,
{
id : { value = rc.id, cfsqltype : "cf_sql_integer, list : true },
idlen : { value = len(rc.id), cfsqltype : "cf_sql_integer" }
}
这里我也给出了关于使 queryparam 有条件的示例代码。出于测试目的,我创建了一些默认参数和值
<cfparam name="id" default="1,2,3,4,5,6">
将查询详细信息设置为字符串并将其保存到另一个变量,如上面提到的@danRoberts。
<cfset MyQry = "SELECT * FROM pages ">
检查 rc.id 值是否为空。如果不是,请附加 IN
子句。
<cfif len(rc.id) >
<cfset MyQry &= " WHERE id IN ( :id ) ">
</cfif>
作为参考,我还添加了一些额外的运算符。
<cfset MyQry &= " limit 10 ">
接下来,基于new 运算符
创建一个新查询<cfset qry = new Query( datasource ='yourDataSource' , sql = MyQry) >
之后,如果rc.id不为空
,则为:ID
添加queryParam
<cfif len(rc.id) >
<cfset qry.addParam( name="id", value="#rc.id#",cfsqltype="cf_sql_varchar",list='true') >
</cfif>
注意:使用IN
运算符时,需要设置
list='true' 查询参数。
然后你执行查询,如下所示
<cfset Result = qry.execute().getResult() >
<cfdump var="#Result#" />
带有queryParam的WHERE
子句只有在rc.ID包含一个值时才会执行。