我已经实现了一个函数,用于检查某个值是否出现在特定表的特定行中:
CREATE FUNCTION check_if_if_exist(id INTEGER, table_name character(50), table_column character(20) ) RETURNS BOOLEAN AS $$
DECLARE res BOOLEAN;
BEGIN
SELECT table_column INTO res
FROM table_name
WHERE table_column = id;
RETURN res;
END;
$$ LANGUAGE plpgsql
我已经创建并填写了一个简单的测试表来试用这个函数:
CREATE TABLE tab(f INTEGER);
我称之为
的功能SELECT check_if_exist(10, tab, f);
但我发生在这个错误中:
ERROR: column "prova" does not exist
LINE 1: SELECT check_if_exist(10, tab, f);
^
********** Error **********
ERROR: column "tab" does not exist
SQL state: 42703
Character: 27
为什么?
答案 0 :(得分:2)
您的代码无法工作 - 在处理PLPGSQL中的不同表时,您需要使用动态查询,因此需要EXECUTE
- http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
但首先 - 使用PostgreSQL EXISTS
- http://www.postgresql.org/docs/current/static/functions-subquery.html#AEN15284而不是发明自己的东西并没有什么不好 - 你的解决方案的性能将比使用附带的电池更糟糕......
希望这很有帮助。祝你好运。
答案 1 :(得分:2)
除了Elmo回复,你必须小心类型。你有:
ERROR: column "tab" does not exist
因为SQL解析器不知道如何处理没有引用的tab
。您的查询必须如下:
SELECT check_if_exist(10, 'tab', 'f');
正如Elmo所说,你使用动态查询,所以即使你引用tab
,你也会收到错误:
ERROR: relation "table_name" does not exist
所以你可以使用EXECUTE
,例如:
CREATE OR REPLACE FUNCTION check_if_exist(id INTEGER, table_name varchar, table_column varchar) RETURNS BOOLEAN AS $$
DECLARE
sql varchar;
cnt int;
BEGIN
sql := 'SELECT count(*) FROM ' || quote_ident(table_name) || ' WHERE ' || quote_ident(table_column) || '=$1';
RAISE NOTICE 'sql %', sql;
EXECUTE sql USING id INTO cnt;
RETURN cnt > 0;
END;
$$ LANGUAGE plpgsql
您还可以在函数参数中使用VARCHAR
代替character(N)
,并使用CREATE OR REPLACE FUNCTION ...
代替CREATE FUNCTION ...
,这在调试时非常方便。