Dev*_*per 3 postgresql dynamic-sql sql-order-by plpgsql
按照此链接中提到的方法,我想ORDER BY动态地传递和排序函数。
ORDER BY工作正常,但我无法通过排序顺序(ASC/ DESC)。
我现在所拥有的:
CREATE OR REPLACE FUNCTION list(_limit integer,_offset integer,sort_by varchar(100), _order varchar(100),_category varchar(100))
RETURNS TABLE(
id INTEGER,
name VARCHAR,
clientname VARCHAR,
totalcount BIGINT
) AS $$
DECLARE empty text := '';
BEGIN
RETURN Query EXECUTE
'SELECT d.id,
d.name,
d.clientname,
count(*) OVER() AS full_count FROM design_list as d
where ($5 = $6 Or d.category Ilike $5)
ORDER BY ' || quote_ident(sort_by) || ' LIMIT $1 offset $2'
USING _limit,_offset,sort_by, _order,_category, empty;
END;$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
我会这样做:
CREATE OR REPLACE FUNCTION list(
_category varchar(100)
, _limit int
, _offset int
, _order_by varchar(100)
, _order_asc_desc text = 'ASC') -- last param with default value
RETURNS TABLE(id int, name varchar, clientname varchar, totalcount bigint) AS
$func$
DECLARE
_empty text := '';
BEGIN
-- Assert valid _order_asc_desc
IF upper(_order_asc_desc) IN ('ASC', 'DESC', 'ASCENDING', 'DESCENDING') THEN
-- proceed
ELSE
RAISE EXCEPTION 'Unexpected value for parameter _order_asc_desc.
Allowed: ASC, DESC, ASCENDING, DESCENDING. Default: ASC';
END IF;
RETURN QUERY EXECUTE format(
'SELECT id, name, clientname, count(*) OVER() AS full_count
FROM design_list
WHERE ($1 = $2 OR category ILIKE $1)
ORDER BY %I %s
LIMIT %s
OFFSET %s'
, _order_by, _order_asc_desc, _limit, _offset)
USING _category, _empty;
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
核心功能:用于format()安全优雅地连接您的查询字符串。有关:
ASC/ DESC(或ASCENDING/ DESCENDING)是固定关键字。我添加了手动check(IF ...),后来用一个简单的串联%s。这是主张法律意见的一种方式。为方便起见,我添加了一条错误消息,用于意外输入和参数默认值,因此该函数默认为ASC调用中省略最后一个参数时。有关:
解决帕维尔的有效评论,我串联_limit和_offset直接,因此查询已经与这些参数的计划。
_limit和_offset是integer参数,因此我们可以使用Plain %s而不会有SQL注入的危险。您可能需要在连接之前声明合理的值(排除负值和过高的值)...
其他说明:
使用一致的命名约定。我前缀的所有参数和变量以下划线_,而不仅仅是一些。
在内部不使用表限定EXECUTE,因为仅涉及一个表,并且表EXECUTE具有单独的作用域。
我重命名了一些参数来阐明。_order_by代替_sort_by; _order_asc_desc代替_order。
| 归档时间: |
|
| 查看次数: |
893 次 |
| 最近记录: |