2

我已经实现了一个函数来检查一个值是否出现在特定表的特定行中:

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

为什么?

4

2 回答 2

4

除了 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 ...

于 2013-07-04T10:45:03.367 回答
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而不是自己发明 - 你的表现解决方案将比使用随附的电池差得多……
希望这会有所帮助。祝你好运。

于 2013-07-04T10:08:04.307 回答