2016-09-15 76 views
2

今天我会根据SQL语句问一个简单的问题(可能几乎是愚蠢的问题)。具有可变条件的SQL

我正在处理SELECT查询,我有一些条件,但并不总是全部。我会用一个例子来解释。

想象一下,一个简单的表的人[ID,姓名,姓]

我希望得到一个人的ID ......我会一直问名字,但并不总是要求为姓,所以查询将取决于PHP函数的参数...查询可能是:

SELECT id FROM Person where name = $name; (if parameter surname = null) 

SELECT id FROM Person where name = $name and surname = $surname;(如果参数姓定义)

我有两个更多钞票码得到它,但我认为它没有优化

选项1:

if ($surname) { 
    SELECT id FROM Person where name = $name and surname = $surname; 
else{ 
    SELECT id FROM Person where name = $name; 
} 

选项2:

$sql = "SELECT id FROM Person where name = $name"; 
if ($surname) { $sql = $sql + " and surname = $surname"; } 

我认为最好的办法是在第二个选项,而参数可能会增加,但我不知道是否它可能是一个灵活的参数,在查询中引入依赖于一个空参数。

对不起,我的英语。

非常感谢。

+1

'... name = $ name and($ surname IS NULL or surname = $ surname)'。 – jarlh

+2

最好的解决方案是使用准备好的语句和@jarlh – Jens

回答

0

你可能想将查询并连接:

$sql="SELECT * FROM Person WHERE 1=1"; 
if(isset($name)) 
{ 
     $sql.= " AND name='$name'";  
} 
if(isset($surname)) 
{ 
     $sql.= " AND surname='$surname'";  
} 
0

我可以提供最佳的解决方案是:

$sql = "SELECT id FROM Person WHERE name = $name and ($surname IS NULL or surname = $surname)"; 
+1

剪下的代码我刚刚看到@jarlh发布了与评论相同的内容。 –

0

谢谢你问!这是一种非常普遍的情况,Sanzeeb的回答是最常见的答案。但是,请注意,您正在砍掉宝贵的sql,并且将来您需要附加一个调试器并即时捕获您的sql以查看实际触及您数据库的请求。

更好的方法是做这一切在SQL中,如下...

var sql = @" 
SELECT id FROM Person where name = $name 
AND (surname = $surname or $surname is null) 
OPTION(RECOMPILE) 
"; 

您请求的可读性得以维持。在这种情况下,OPTION(RECOMPILE)可能是矫枉过正的,但建议用于可选参数,因为它允许db针对提供的特定参数组合进行优化。

一个更好的选择是将上述请求粘贴到QueryFirst .sql模板中,并删除所有触发你的SQL的诱惑! QueryFirst将提供很多帮助,它会自动将C#中的空值转换为DBNull.Value,因此SQL中的值为NULL。