我正在尝试了解以下Coldfusion / MySQL查询中发生的事情,我不得不更新(我在CF / MySQL的第一个月)。
我在搜索之前运行了一个查询,它设置变量 pl (价格表),如下所示:
<cfif variables.module IS "yes">
<cfquery datasource="ds" name="qp">
<!--- selects pricelist and seller --->
</cfquery>
<cfset variables.pl = "LEFT JOIN pricelist p ON ">
<cfoutput query="qp" >
<cfif qp.preislist IS ''>
<cfset variables.pl= variables.pl & '(p.iln = a.iln AND p.preislist = "AAA" AND p.ean = a.ean AND p.iln = "#qp.seller#") OR '>
<cfelse>
<cfset variables.pl= variables.pl & '(p.iln = a.iln AND p.preisliste = "#qp.preislist#" AND p.ean = a.ean AND p.iln = "#qp.seller#") OR '>
</cfif>
</cfoutput>
<cfset variables.pl = variables.preislisten & "(1=0)">
</cfif>
然后将其“移植”到搜索查询中,这样就增加了我的困惑:
<cfquery datasource="ds" name="getArt">
SELECT a.* <cfif variables.module IS "yes">, p.ek, p.vk, p.waehrung, p.onlinepreis</cfif>
FROM artdata a
<cfif variables.module IS "yes">
<cfqueryparam cfsqltype="cfsql_varchar" value="#variables.pl#">
</cfif>
....
很多问题:
- 不需要cfparam查询字段,例如 qp.seller ,或者是否存在?
- 我不应该像在 artdata AS 中一样使用ALIAS而只使用 artdata a 吗?
- 我可以像这样选择 p.ek,p.vk,... 虽然价格表只会在稍后通过变量 variables.pl (正在< em> LEFT JOIN pricelist p ON ...)
- (1 = 0)怎么了?它的目的是什么? Dito为(3 = 2),(1 = 2)。
感谢您的一些启示!
答案 0 :(得分:3)
不需要cfparam查询字段,如qp.seller,还是有?
它不是cfparam它的cfqueryparam - 这是两个执行不同任务的不同标签。
使用cfqueryparam有两个主要原因:
1)为了安全起见 - 如果输入可能最初来自任何第三方,或者如果您不能保证输入是已知值,请使用cfqueryparam确保不会发生SQL代码注入(有意或无意)。
2)对于性能 - 查询参数导致执行计划可以缓存并应用于多个查询(即参数变化的地方),因此通常可以提高性能。
如果qp.seller是一个保证安全的数字外键,你不需要它来保证安全性,但它仍然可能从性能方面产生有益效果。
一般来说,如有疑问,请使用。
(偶尔会有人声称它会导致糟糕的执行计划导致性能下降,但我对这些声明持谨慎态度,并且在任何情况下都必须在个案中处理案例基础 - 安全很重要。)
我不应该像artdata AS一样使用ALIAS而只使用artdata a?
如果你喜欢打字更多。 :)
表名称的AS关键字没有区别/好处。
我可以选择p.ek,p.vk,......像这样
是的,那会有用。
可能喜欢将它们放在多行上,以使其更具可读性。
虽然价格表只会在稍后通过变量&gt;声明。 variables.pl(LEFT JOIN pricelist p ON ...)
这是一个不正确的假设。
使用cfqueryparam专门防止SQL代码被注入,这就是你在这里尝试使用它。
您应该将此生成的SQL直接输出到将在其中使用的cfquery标记中,而不是创建variables.pl。
(如果你不确定我的意思,我可以为此做一个例子吗?)
(1 = 0)怎么了?它的目的是什么? Dito为(3 = 2),(1 = 2)。
正如Romain的评论所解释的那样,这是一种常见的说法,用于动态查询时使用。括号是可选的。
然而,更常见的是将它放在 start - 即WHERE 1=0
或JOIN 1=0
- 然后让动态语句从OR ...
开始。< / p>
答案 1 :(得分:2)
- 不需要cfparam查询字段,例如qp.seller,还是有?
首先,这是cfqueryparam
,而不是cfparam
。 cfqueryparam
用于数据清理。 cfparam
用于确保变量存在某种值。是否需要使用它?如果你明确地创建/设置variables.pl,那么没有。但它仍然是一个很好的做法。如果您或其他人稍后更改设置代码,则cfqueryparaming数据可确保数据完整性。它还可以帮助您一目了然地知道变量包含哪种数据。
- 我不应该像artdata AS一样使用ALIAS而只使用artdata吗?
据我所知,你应该这样做。我使用的所有数据库都支持tablename alias
语法,但我相信 ANSI标准是使用AS
,这将使您的代码更具可移植性。
- 我可以选择p.ek,p.vk,......就像这样,虽然pricelist表只会在稍后通过变量variables.pl声明(LEFT JOIN pricelist p ON ...) 强>
是。这很常见(至少在我工作的地方)。
- (1 = 0)怎么了?它的目的是什么? Dito为(3 = 2),(1 = 2)。
罗曼在评论中得到了很好的回答。这是一个强制的真/假值。它通常在动态生成SQL语句时使用,以确保生成至少一个WHERE
子句。
答案 2 :(得分:2)
关于“不需要cfparam查询字段,例如qp.seller,或者是否存在?”:我还没有看到的一件事是cfqueryparam仅在cfquery标签的上下文中有效。由于您正在构建cfquery标记上下文之外的SQL块,因此您将无法在其中使用cfqueryparam来获取qp.seller。因此,您有一些选择 -
其他海报已经很好地回答了你的其他问题 - 我没有更多的东西可以补充。