POSTGRES:函数接受hashmap或类似的类型作为参数

时间:2014-10-07 17:31:21

标签: sql database postgresql stored-procedures plpgsql

有没有办法将hashmap(或类似的数据类型)作为参数传递给postgres函数?

我正在尝试获得一个可以接受不同的功能。不同情况下的论据。而且我不想为那些与特定调用者无关的参数传递空值或0。

我想要实现的例子(原谅伪代码)

function(hashmap map) {
condition = 'where ';
 for (entry : map) {
  condtion = condition || map.key || '=' || map.value;
 }
  sql := sql || condition;
  //execute sql
}

有没有办法在postgres中实现这个目标?

1 个答案:

答案 0 :(得分:1)

对于您的用例,您可以使用hstore或两个数组或2D数组。您的示例很好地演示了SQL注入,因此您不应忘记必要的转义。

CREATE OR REPLACE FUNCTION hstore_params(filters hstore)
RETURNS text AS $$
BEGIN
  RETURN 'SELECT * FROM some_table ' ||
            coalesce ('WHERE ' ||
            ( SELECT string_agg(quote_ident(key) || ' = ' || quote_literal(value), ' and ') 
                 FROM each('c1 => Ahoj, c2 => Nazdar'::hstore). '') );
END;
$$ LANGUAGE plpgsql;
postgres=# SELECT hstore_params('c1 => Ahoj, c2 => Nazdar');
                        hstore_params                         
--------------------------------------------------------------
 SELECT * FROM some_table WHERE c1 = 'Ahoj' and c2 = 'Nazdar'
(1 row)

下一种可能性是使用函数默认参数。这是我个人的最爱:

CREATE OR REPLACE FUNCTION hstore_params(c1 text DEFAULT NULL, c2 text DEFAULT NULL)
RETURNS text AS $$
BEGIN 
  EXECUTE 'SELECT * 
             FROM xx
            WHERE (c1 = $1 OR c1 IS NULL) 
              AND (c2 = $2 OR c2 IS NULL)'
    USING c1, c2;
  RETURN 'ok';
END;
$$ LANGUAGE plpgsql;
postgres=# SELECT hstore_params();
 hstore_params 
---------------
 ok
(1 row)

postgres=# SELECT hstore_params('Ahoj','Nazdar');
 hstore_params 
---------------
 ok
(1 row)

postgres=# SELECT hstore_params('Ahoj');
 hstore_params 
---------------
 ok
(1 row)

postgres=# SELECT hstore_params(c2 := 'Ahoj');
 hstore_params 
---------------
 ok
(1 row)