PL / PgSQL在CREATE VIEW中将变量名称视为列名

时间:2014-03-31 02:03:59

标签: sql postgresql

我有一个类似的功能:

CREATE FUNCTION func(TEXT) RETURNS TEXT AS $$
DECLARE
v_name1 ALIAS FOR $1;

BEGIN

SELECT * from table1 WHERE names_column = v_name1;
RETURN v_name1;

END;
$$ LANGUAGE plpgsql;

如果我这样做

SELECT func('Alex');

它应该运行:

SELECT * from table1 WHERE names_column = 'Alex';

但我得到了这个错误:

ERROR:  column "v_name1" does not exist
LINE 2: SELECT * FROM table1 WHERE names_column = v_name1;

如何告诉Postgres将变量中的TEXT进行比较?

[编辑]这是我到目前为止产生错误的函数:

CREATE OR REPLACE FUNCTION get_champ(end_date DATE, champ_name TEXT) RETURNS TEXT AS $$
DECLARE
new_champ_name TEXT;
id_of_new_champ INTEGER;
date_of_new_champ DATE;
BEGIN

CREATE OR REPLACE VIEW champ AS
SELECT * FROM basketball2 WHERE visitor = champ_name OR home = champ_name;

SELECT MIN(id) INTO id_of_new_champ FROM champ WHERE winner <> champ_name;
SELECT date INTO date_of_new_champ FROM basketball2 WHERE id = id_of_new_champ;
SELECT winner INTO new_champ_name FROM basketball2 WHERE id = id_of_new_champ;
RETURN new_champ_name;

END;
$$ LANGUAGE plpgsql;

1 个答案:

答案 0 :(得分:3)

CREATE OR REPLACE VIEW不是PostgreSQL中的 plannable statement ,它是DDL。

这意味着它无法接受查询参数。因此,PL / PgSQL将PL / PgSQL变量正常转换为查询参数是不可用的。它将字面上的查询视为书面形式。

要获得所需的结果,必须使用EXECUTE的动态SQL,例如

 EXECUTE format('CREATE OR REPLACE VIEW champ AS
 SELECT * FROM basketball2 WHERE visitor = %L OR home = %L', champ_name, champ_name);

...但在这种情况下,首先创建视图似乎是荒谬的。你为什么要这样做,它什么也得不到你。只需写下:

SELECT MIN(id) 
INTO id_of_new_champ 
FROM basketball2 
WHERE (visitor = champ_name OR home = champ_name)
  AND winner <> champ_name;

此外,从不“简化”或“匿名化”您的代码,而明确表示您已经在问题中,并且*使用简化代码测试问题仍然存在。否则你只是在浪费你的时间和其他人。