简体   繁体   English

Postgres动态查询功能

[英]Postgres Dynamic Query Function

I need to create a function that will run a query and return the results with the table name and the column name being arugments given to the function. 我需要创建一个函数,该函数将运行查询并以表名和列名作为给该函数的前景色返回结果。 I currently have this: 我目前有这个:

CREATE OR REPLACE FUNCTION qa_scf(tname character varying, cname character varying)
RETURNS SETOF INT AS
$BODY$
BEGIN
RETURN QUERY SELECT * FROM tname WHERE cname !='AK' AND cname!='CK';
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;

This gives me the error "Relation 'tname' des not exist" when run. 这在运行时给我错误“关系'tname'不存在”。 I'm new to function creating for Postgres, so any help is appreciated. 我是Postgres函数创建的新手,所以对您的帮助表示赞赏。 I feel like the return int is wrong, but I don't know what else to put to make it return all columns for the rows returned. 我觉得return int是错误的,但是我不知道要放什么使其返回返回行的所有列。 Thanks! 谢谢!

You cannot use a variable in place of an identifier like that. 您不能使用变量代替这样的标识符。 You need to do it with dynamic queries. 您需要使用动态查询来完成。 It will look something like this: 它看起来像这样:

EXECUTE 'SELECT * FROM ' || quote_ident(tname) 
        || ' WHERE ' || quote_ident(cname) || ' NOT IN (''AK'',''CK'');'
INTO result_var;

If you are using PostgreSQL 9.1 or above, you can use the format() function which makes constructing this string much easier. 如果您使用的是PostgreSQL 9.1或更高版本,则可以使用format()函数 ,该函数使构造此字符串更加容易。

Table and column names can not be specified as parameters or variables without dynamically constructing a string to execute as a dynamic statement. 在没有动态构造要作为动态语句执行的字符串的情况下,不能将表名和列名指定为参数或变量。 Postgres has excellent introductory documentation about executing dynamic statements . Postgres提供了有关执行动态语句的出色入门文档。 It's important to properly quote identifiers and literals with quote_ident() or quote_literal() . 重要的是要使用quote_ident()quote_literal()正确引用标识符和文字。 The format() function helps clean up dynamic sql statement construction. format()函数有助于清理动态sql语句的构造。 Since you declare the function to return SETOF INTEGER , you should select the integer field you want, not * . 由于您声明了要返回SETOF INTEGER的函数,因此应选择所需的整数字段,而不是*

CREATE OR REPLACE FUNCTION qa_scf(tname text, cname text)
RETURNS SETOF INTEGER AS
$BODY$
BEGIN
  RETURN QUERY EXECUTE format(
    'SELECT the_integer_field FROM %I WHERE %I NOT IN (%L,  %L)',
                                   tname,   cname,    'AK', 'CK'
  );
END;
$BODY$
LANGUAGE plpgsql;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM