【发布时间】:2016-05-31 04:50:46
【问题描述】:
是否有使用可选参数创建搜索查询的通用模式?我在想我们应该能够构建一个多部分的where 子句,但取消未指定的部分。此外,某些查询参数可能需要连接,如果未指定关联的查询参数,我想取消它们。
示例(查看完整代码here)
想想人员配备领域。它由项目、需求、人员和技能组成。我们希望根据以下条件搜索需求:
1. min_start_date
2. max_start_date
3. project_id
4. project_location
5. skill_id
以下是相关表格:
CREATE TABLE projects (
id SERIAL PRIMARY KEY,
name VARCHAR(64),
location VARCHAR(3) NOT NULL
);
CREATE TABLE needs (
id SERIAL PRIMARY KEY,
start_date TIMESTAMPTZ,
end_date TIMESTAMPTZ,
project_id INTEGER NOT NULL,
skill_id INTEGER NOT NULL
);
CREATE TABLE skills (
id SERIAL PRIMARY KEY,
name VARCHAR(64) NOT NULL
);
这是搜索的查询:
\set min_start_date '2016-08-01T00:00:00-04'
\set max_start_date '2016-08-31T00:00:00-04'
\set project_id 71
\set project_location 'DEN'
\set skill_id 4
SELECT n.id, n.start_date, n.end_date
FROM needs n
LEFT OUTER JOIN projects p
ON n.project_id = p.id
WHERE n.start_date >= :'min_start_date'
AND n.start_date < :'max_start_date'
AND p.id = :'project_id'
AND p.location = :'project_location'
AND s.id = :'skill_id'
ORDER BY n.start_date, p.id, s.id;
我想要的是根据指定的查询参数使 where 子句的部分无效的能力。如果没有指定搜索参数project_location,也应该不需要执行join。
编辑
根据 Neil McGuigan 的评论,我尝试了这个:
\set min_start_date 2016-08-01T00:00:00-04
SELECT *
FROM needs n
WHERE (:'min_start_date' IS NULL OR n.start_date >= :'min_start_date');
这可以正常工作并产生所需的结果,但是当我将 min_start_date 的值更改为 NULL 时:
\set min_start_date NULL
我从 PostgreSQL 收到以下错误:
ERROR: invalid input syntax for type timestamp with time zone: "NULL"
LINE 8: WHERE ('NULL' IS NULL OR n.start_date >= 'NULL')
^
基本上我无法为 OR 的两边提供正确的类型。不确定如何指定 NULL 参数值,SQL 语句是否可以工作。
【问题讨论】:
-
如果您为不需要的参数提供 NULL 值当然是可能的,但您应该动态生成查询并且不包括这些部分。
-
当您说动态生成查询时,您的意思是字符串连接以每次都生成自定义查询吗?那意味着根本没有准备好的陈述,对吗?我希望有更好的方法。
-
您似乎在引用您的绑定变量 - 没有必要 - 您正在检查字符串
'NULL'是否为 NULL,或者日期是否大于或等于字符串。 -
好吧,我被两种方式都困住了,如果我引用它们,那么我将
'NULL'与NULL进行比较,如果我不引用它们,那么我在 WHERE 子句中出现语法错误:语法“T00”或附近的错误:WHERE (2016-08-01T00:00:00-04...
标签: sql postgresql