我一直在寻找一段时间,尝试在SO中找到很多代码,但没有一个能够工作。所以我问了一个新问题。
在PostgreSQL函数中,我试图返回一个SETOF bigint(一堆表中的id),但是根据第一个输入($1
),查询会有所不同。所以我在该函数中也有一个SELECT CASE
。
目前,该功能如下所示:
CREATE OR REPLACE FUNCTION get_employee_ids(int, int, int, int, text, int)
RETURNS SETOF bigint AS
$BODY$
SELECT CASE
WHEN $1 = 1 THEN
SELECT employee_id FROM employee WHERE period = $2 AND payment >= $3 AND operation = $4
INTERSECT
SELECT employee_id FROM employee WHERE period IN $5
WHEN $1 = 2 THEN
SELECT employee_id FROM employee WHERE period BETWEEN $1 AND $6 AND payment >= $2 AND operation = $3
INTERSECT
SELECT employee_id FROM employee WHERE period IN $5
WHEN $1 = 3 THEN
SELECT employee_id FROM employee WHERE period BETWEEN $1 AND $6 AND payment >= $2 AND operation != $3
INTERSECT
SELECT employee_id FROM employee WHERE period IN $5
WHEN $1 = 4 THEN
SELECT employee_id FROM employee WHERE period BETWEEN $1 AND $6 AND payment < $2 AND operation = $3
INTERSECT
SELECT employee_id FROM employee WHERE period IN $5
END
$BODY$
LANGUAGE sql VOLATILE;
在这种情况下,错误是SELECT附近的语法错误。
问题似乎是SELECT
没有执行。但我也尝试使用RETURN QUERY
,EXECUTE
,RETURN QUERY EXECUTE
以及其他答案中的许多其他内容。
我该如何做到这一点?
修改
有用的信息,这就是我使用这个函数的方式:get_employee_ids(4, 1108, 250, 97, "(1109,1110)", 0808)
答案 0 :(得分:2)
使用@klin建议的整数数组和更简单的查询:
create or replace function get_employee_ids (
int, int, int, int, int[], int
) returns setof bigint as
$body$
select employee_id
from employee
where
(
($1 in (1, 4) and payment < $2 and operation = $3)
or
($1 = 2 and payment >= $2 and operation = $3)
or
($1 = 3 and payment >= $2 and operation != $3)
)
and period = ANY ($5)
and period between $1 and $6
$body$
language sql volatile;
顺便说一下,它似乎可以stable
代替volatile
答案 1 :(得分:1)
第五个参数是一个文本,它将成为查询的一部分。您不能以这种方式构建查询。
将参数类型更改为integer[]
,然后使用ANY
代替IN
。
CREATE OR REPLACE FUNCTION get_employee_ids(int, int, int, int, int[], int)
RETURNS SETOF bigint AS
$BODY$
SELECT CASE
WHEN $1 = 1 THEN
(SELECT employee_id FROM employee WHERE period = $2 AND payment >= $3 AND operation = $4
INTERSECT
SELECT employee_id FROM employee WHERE period = ANY ($5))
WHEN $1 = 2 THEN
(SELECT employee_id FROM employee WHERE period BETWEEN $1 AND $6 AND payment >= $2 AND operation = $3
INTERSECT
SELECT employee_id FROM employee WHERE period = ANY ($5))
WHEN $1 = 3 THEN
(SELECT employee_id FROM employee WHERE period BETWEEN $1 AND $6 AND payment >= $2 AND operation != $3
INTERSECT
SELECT employee_id FROM employee WHERE period = ANY ($5))
WHEN $1 = 4 THEN
(SELECT employee_id FROM employee WHERE period BETWEEN $1 AND $6 AND payment < $2 AND operation = $3
INTERSECT
SELECT employee_id FROM employee WHERE period = ANY ($5))
END
$BODY$
LANGUAGE sql VOLATILE;
-- usage:
SELECT get_employee_ids(4, 1108, 250, 97, array[1109,1110], 0808);