![](/img/trans.png)
[英]Hibernate: PSQLException: Error: Column “column_name” does not exist
[英]Postgres pl/pgsql ERROR: column "column_name" does not exist
我有一個如下所示的存儲程序,
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;
當我執行這樣的查詢時:
select * from select_transactions3("invoice_no", '1103300105472',10);
或者
select * from select_transactions3(invoice_no, '1103300105472',10);
它得到這樣的錯誤:錯誤:列“invoice_no”不存在
但是當我嘗試像這樣使用一個冒號執行時:
select * from select_transactions3('invoice_no', '1103300105472',10);
結果是沒有行。
我怎樣才能得到這樣的數據:
invoice_no | trans_date
---------------+-------------------------
1103300105472 | 2011-03-30 12:25:35.694
謝謝 。
更新:如果我們想要我們想要顯示的表的某一列
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;
得到結果:
SELECT * FROM select_to_transactions14( 'invoice_no', '1103300105472',1)
as ("invoice_no" varchar(125), "amount" numeric(12,2));
您的函數可能如下所示:
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;
在 PostgreSQL 9.1或更高版本中,使用format()
更簡單
...
RETURN QUERY EXECUTE format('
SELECT *
FROM transactions
WHERE %I = $1
LIMIT $2', _col)
USING _val, _limit;
...
%I
轉義諸如quote_ident()
類的標識符。
您遇到了不能將參數用作標識符的動態 SQL 的限制。 您必須使用列名構建查詢字符串,然后執行它。
不過,您可以使用值來做到這一點。 我演示了EXECUTE
的USING
子句的使用。 還要注意quote_ident()
的使用:防止 SQL 注入和某些語法錯誤。
我還大大簡化了您的功能。 [RETURN QUERY EXECUTE][3]
使您的代碼更短、更快。 如果您所做的只是返回該行,則無需循環。
我使用命名的IN
參數,因此您不會對查詢字符串中的 $-notation 感到困惑。 查詢字符串中的$1
和$2
指的是USING
子句中提供的值,而不是輸入參數。
我更改為SELECT *
因為您必須返回整行以匹配聲明的返回類型。
最后但同樣重要的是:請務必考慮手冊對聲明為SECURITY DEFINER
的函數的說明。
如果您不想返回整行,一種方便的可能性是:
CREATE FUNCTION select_transactions3(_col text, _val text, _limit int)
RETURNS TABLE (invoice_no varchar(125), amount numeric(12,2) AS ...
然后,您不必在每次調用時都提供列定義列表,並且可以簡化為:
SELECT * FROM select_to_transactions3('invoice_no', '1103300105472', 1);
您可以從服務器查詢所有數據庫,並根據您自己的數據庫進行排序。
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tableName';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.