如何在引用时检查PostgreSQL中的值是否为NULL?

时间:2014-05-01 21:52:05

标签: sql c postgresql

我有以下SQL查询:

SELECT choice, COUNT(*) AS c
FROM Vote, Person
WHERE Vote.pid = Person.pid AND (Person.city = '%s' OR %s IS NULL) <-----
GROUP BY choice
ORDER BY c DESC, choice

我已添加Person.city = '%s' OR %s IS NULL部分,因此,如果参数为NULL,则查询将包含所有城市。当参数为NULL时,此查询可以正常工作,但当我输入非NULL值时,比如Paris,我收到此错误:

  

错误:专栏&#34;巴黎&#34;在角色104不存在

据我所知,发生此错误是因为%s未被引用。但是当我引用它时,如果%s为NULL,则'%s' IS NULL不会评估为true。

我如何检查%s引用时NULL是否为{{1}}?

3 个答案:

答案 0 :(得分:0)

也许你可以试试:

SELECT choice, COUNT(*) AS c
FROM Vote join
     Person
     on Vote.pid = Person.pid 
WHERE (Person.city = '%s' OR '%s' = 'NULL') 
GROUP BY choice
ORDER BY c DESC, choice;

您无法明确搜索&#34; NULL&#34;,但这可能是一个很小的代价。

注意我还将连接语法更改为使用显式join语法。

答案 1 :(得分:0)

如果你的变量不是NULL,你的查询应该是: SELECT choice, COUNT(*) AS c FROM Vote as V join Person as P on V.pid = P.pid WHERE P.city = '%s' GROUP BY choice ORDER BY c DESC, choice;

...如果%s为NULL:

SELECT choice, COUNT(*) AS c FROM Vote as V join Person as P on V.pid = P.pid GROUP BY choice ORDER BY c DESC, choice;

绝对不是最简洁的方式,但肯定是最清晰的。

我最初误解了这个问题,为此我道歉。希望有所帮助...

答案 2 :(得分:0)

您应该使用预备语句。本相关答案中C的详细说明:
Passing C variables into SQL command

然后将值作为传递,而不是尝试字符串连接,这也可以打开 SQL注入

您的查询可能如下所示(在JOINGROUP BY中使用明确的ORDER BY语法和位置参数进行了简化:

SELECT v.choice, count(*) AS c
FROM   vote v
JOIN   person p USING (pid)
WHERE (p.city = $1 OR $1 IS NULL)
GROUP  BY 1
ORDER  BY 2 DESC, 1;

此处不需要括号 - 仅当您在AND之前OR绑定后添加更多条件。

或者您创建一个PL / pgSQL函数,以更智能的方式处理NULL案例。昨天我写了一个详细的相关答案:
How to remove conditions from WHERE clause if parameters are NULL

如果保证参照完整性(由外键约束强制执行)并且每个投票都有相关人员,则在NULL值的情况下简化函数调用:

SELECT v.choice, count(*) AS c
FROM   vote v
GROUP  BY 1
ORDER  BY 2 DESC, 1;