[英]Postgres pl/pgsql ERROR: column "column_name" does not exist
i have a storerd procedure like below,我有一个如下所示的存储程序,
CREATE FUNCTION select_transactions3(text, text, int)
RETURNS SETOF transactions AS
$body$
DECLARE
rec transactions%ROWTYPE;
BEGIN
FOR rec IN (SELECT invoice_no, trans_date FROM transactions WHERE $1 = $2 limit $3 )
LOOP
RETURN NEXT rec;
END LOOP;
END;
$body$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
when i execute query like this :当我执行这样的查询时:
select * from select_transactions3("invoice_no", '1103300105472',10);
or或者
select * from select_transactions3(invoice_no, '1103300105472',10);
it getting error like this : ERROR: column "invoice_no" does not exist它得到这样的错误:错误:列“invoice_no”不存在
but when i try execute with one colon like this :但是当我尝试像这样使用一个冒号执行时:
select * from select_transactions3('invoice_no', '1103300105472',10);
the result is no row.结果是没有行。
how i can get the data like this :我怎样才能得到这样的数据:
invoice_no | trans_date
---------------+-------------------------
1103300105472 | 2011-03-30 12:25:35.694
thanks .谢谢 。
UPDATE : If we want a certain column of table that we want to show更新:如果我们想要我们想要显示的表的某一列
CREATE FUNCTION select_to_transactions14(_col character varying, _val character varying, _limit int)
RETURNS SETOF RECORD AS
$$
DECLARE
rec record;
BEGIN
FOR rec IN EXECUTE 'SELECT invoice_no, amount FROM transactions
WHERE ' || _col || ' = $1 LIMIT $2' USING _val, _limit LOOP
RETURN NEXT rec;
END LOOP;
END;
$$ LANGUAGE plpgsql;
to get the result :得到结果:
SELECT * FROM select_to_transactions14( 'invoice_no', '1103300105472',1)
as ("invoice_no" varchar(125), "amount" numeric(12,2));
Your function could look like this:您的函数可能如下所示:
CREATE FUNCTION select_transactions3(_col text, _val text, _limit int)
RETURNS SETOF transactions AS
$BODY$
BEGIN
RETURN QUERY EXECUTE '
SELECT *
FROM transactions
WHERE ' || quote_ident(_col) || ' = $1
LIMIT $2'
USING _val, _limit;
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
IN PostgreSQL 9.1 or later that's simpler with format()
在 PostgreSQL 9.1或更高版本中,使用
format()
更简单
...
RETURN QUERY EXECUTE format('
SELECT *
FROM transactions
WHERE %I = $1
LIMIT $2', _col)
USING _val, _limit;
...
%I
escapes identifiers like quote_ident()
. %I
转义诸如quote_ident()
类的标识符。
You were bumping into the limitation of dynamic SQL that you cannot use parameters for identifiers.您遇到了不能将参数用作标识符的动态 SQL 的限制。 You have to build the query string with the column name and then execute it.
您必须使用列名构建查询字符串,然后执行它。
You can do that with values though.不过,您可以使用值来做到这一点。 I demonstrate the use of the
USING
clause for EXECUTE
.我演示了
EXECUTE
的USING
子句的使用。 Also note the use of quote_ident()
: prevents SQL injection and certain syntax errors.还要注意
quote_ident()
的使用:防止 SQL 注入和某些语法错误。
I also largely simplified your function.我还大大简化了您的功能。
[RETURN QUERY EXECUTE][3]
makes your code shorter and faster. [RETURN QUERY EXECUTE][3]
使您的代码更短、更快。 No need to loop if all you do is return the row.如果您所做的只是返回该行,则无需循环。
I use named IN
parameters, so you don't get confused with the $-notation in the query string.我使用命名的
IN
参数,因此您不会对查询字符串中的 $-notation 感到困惑。 $1
and $2
inside the query string refer to the values provided in the USING
clause, not to the input parameters.查询字符串中的
$1
和$2
指的是USING
子句中提供的值,而不是输入参数。
I change to SELECT *
as you have to return the whole row to match the declared return type anyway.我更改为
SELECT *
因为您必须返回整行以匹配声明的返回类型。
Last but not least: Be sure to consider what the manual has to say about functions declared SECURITY DEFINER
.最后但同样重要的是:请务必考虑手册对声明为
SECURITY DEFINER
的函数的说明。
If you don't want to return the whole row, one convenient possibility is:如果您不想返回整行,一种方便的可能性是:
CREATE FUNCTION select_transactions3(_col text, _val text, _limit int)
RETURNS TABLE (invoice_no varchar(125), amount numeric(12,2) AS ...
Then you don't have to provide a column definition list with every call and can simplify to:然后,您不必在每次调用时都提供列定义列表,并且可以简化为:
SELECT * FROM select_to_transactions3('invoice_no', '1103300105472', 1);
You can query all databases from the server and sort them according to your own database.您可以从服务器查询所有数据库,并根据您自己的数据库进行排序。
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tableName';
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.