Можно ли создать функцию в PostgreSQL, которая принимает имя столбца в качестве входных данных? - PullRequest
3 голосов
/ 07 декабря 2011

У меня есть две таблицы, подобные этой:

CREATE TABLE table1_lang
(
  id serial NOT NULL,
  lang1 character varying,
  lang2 character varying,
  ...
)

CREATE TABLE table2_lang
(
  id serial NOT NULL,
  table1_id NOT NULL,
  lang1 character varying,
  lang2 character varying,
  ...
)

Каждый из столбцов lang содержит имя на разных языках.Я хочу создать функцию, которая возвращает выбранный язык из table1_lang, если он существует.Если имя не существует в table1_lang, то функция должна вернуть имя из table2_lang.

Пока что я решил свою проблему с этой функцией в plpgsql:

CREATE OR REPLACE FUNCTION get_name(integer, text)
  RETURNS character varying AS
$BODY$
DECLARE
    in_id ALIAS FOR $1;
    lang ALIAS FOR $2;
    table1_name varchar;
    table2_name varchar;
BEGIN
    IF lang IS NOT NULL AND lang = 'lang1' THEN
        SELECT a.lang1 INTO table1_name
            FROM table1_lang a
            WHERE a.id = in_id;

            IF table1_name IS NOT NULL AND length(table1_name) > 0 THEN
            RETURN table1_name;
        ELSE
            SELECT a.lang1 INTO table2_name
            FROM table2_lang a
            WHERE a.table1_id = in_id;

            IF table2_name IS NOT NULL AND length(table2_name) > 0 THEN
                RETURN table2_name;
            END IF;
        END IF; 
    END IF;

    IF lang IS NOT NULL AND lang = 'lang2' THEN
        SELECT a.lang2 INTO table1_name
            FROM table1_lang a
            WHERE a.id = in_id;

            IF table1_name IS NOT NULL AND length(table1_name) > 0 THEN
            RETURN table1_name;
        ELSE
            SELECT a.lang2 INTO table2_name
            FROM table2_lang a
            WHERE a.table1_id = in_id;

            IF table2_name IS NOT NULL AND length(table2_name) > 0 THEN
                RETURN table2_name;
            END IF;
        END IF;             
    END IF;

    ...

    IF table2_name IS NULL OR length(table2_name) = 0 THEN
        RETURN NULL;
    END IF;

END
$BODY$
  LANGUAGE plpgsql VOLATILE STRICT
  COST 100;
ALTER FUNCTION get_name(integer, text) OWNER TO postgres;

Но я бы хотелчтобы узнать, возможно ли создать функцию в plpgsql или других языках, доступных в PostgreSQL, которая принимает столбец в качестве входного параметра?

1 Ответ

5 голосов
/ 07 декабря 2011

Это возможно в функции plpgsql.Но если идентификаторы (включая имена столбцов) параметризованы, вы должны построить динамический SQL и выполнить его с EXECUTE.Читайте об этом в руководстве здесь .Обратите внимание, чтобы не делать инъекцию SQL таким образом.Используйте quote_ident() или format().

Я написал пару похожих ответов со ссылками и пояснениями.Попробуйте этот для начала или этот .

...