PostgreSQL中的动态限制

时间:2015-09-15 08:55:36

标签: postgresql

我有函数返回Employees列表,我的要求是如果我传递Limit to function而不是我应该得到带限制和偏移的结果,如果我没有通过限制而不是所有行都应该返回

例如

When Limit is greater than 0(I am passing Limit as 10)
Select * from Employees
Limit 10 offset 0

When Limit is equal to 0 than
Select * from Employees

他们是否有办法在功能上做这样的逻辑?

3 个答案:

答案 0 :(得分:3)

是的,您可以传递LIMITOFFSET子句的表达式,其中包括使用传入函数的参数。

CREATE FUNCTION employees_limited(limit integer) RETURNS SET OF employees AS $$
BEGIN
  IF limit = 0 THEN
    RETURN QUERY SELECT * FROM employees;
  ELSE
    RETURN QUERY SELECT * FROM employees LIMIT (limit)
  END IF;
  RETURN;
END; $$ LANGUAGE plpgsql STRICT;

请注意LIMIT子句周围的括号。您可以类似地传入OFFSET值。

但这个例子非常简单。您可以通过在函数外部执行LIMIT来实现相同的效果:

SELECT * FROM my_function() LIMIT 10;

在函数内部执行此操作实际上仅对复杂查询有用,可能涉及大量数据。

另请注意,没有LIMIT的{​​{1}}子句会产生不可预测的结果。

答案 1 :(得分:1)

抱歉,我无法发表评论。解决方案几乎由Patrick提供。
首先我们应该编写函数来无限制地返回结果。

CREATE FUNCTION test () 
RETURNS TABLE (val1 varchar, val2 integer) AS $$
    BEGIN
    RETURN QUERY SELECT val1, val2 FROM test_table;
    END;
$$ LANGUAGE plpgsql;

然后我们必须编写包装函数,它将处理限制。

CREATE FUNCTION test_wrapper (l integer DEFAULT 0)
RETURNS TABLE (name varchar, id integer) AS $$
    BEGIN
        IF l = 0 THEN
            RETURN QUERY SELECT * FROM test(); -- returns everything
        ELSE
            RETURN QUERY SELECT * FROM test() LIMIT (l); -- returns accordingly
        END IF;
    END;
$$ LANGUAGE plpgsql;

在我的情况下,我需要返回表作为最终结果,但是可以从包装函数返回所需的任何内容。

答案 2 :(得分:0)

请注意,带有LIMIT的SELECT应始终包含ORDER BY,因为如果没有明确指定,则返回行的顺序可能是未定义的。

LIMI的Insead你可以像下面的查询一样使用ROW_NUMBER():

SELECT *
FROM (
  SELECT *, row_number() OVER (ORDER BY id) AS rn
  FROM Employees
) AS s
WHERE
  (rn>:offset AND rn<=:limit+:offset) OR :limit=0