Необычный синтаксис UPDATE в хранимой процедуре - PullRequest
0 голосов
/ 17 января 2019

Мне нужна помощь в понимании этой хранимой процедуры, которую я обнаружил в устаревшей системе, которую я проверяю. В частности, я не могу понять команду UPDATE внутри условного IF: UPDATE authors.author_id ....

DECLARE

    p_mem_id ALIAS FOR $1;
    p_auth_id ALIAS FOR $2;

    res     bool ;
    v_rec   authors.author_gov_id%ROWTYPE;

    BEGIN
        res := 0;
        SELECT INTO v_rec * FROM authors.author_gov_id WHERE author_id = p_auth_id;

        IF FOUND THEN
              UPDATE authors.author_id = (SELECT gov_id FROM authors.gov_id WHERE mem_id=p_mem_id);
        ELSE
              .. snip ..
        END IF;

        RETURN res;
    END;

Я нахожу это сбивающим с толку, потому что этот оператор обновления кажется неподдерживаемым синтаксисом [1] в моей версии PSQL (без SET и прямого назначения), и потому что в моей базе данных нет отношения с именем authors.author_id (ничего в pg_proc тоже).

my_database=# \d authors.author_id;
Did not find any relation named "authors.author_id".

[1] https://www.postgresql.org/docs/9.3/sql-update.html

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Как уже отмечали другие, это неверный синтаксис.

Однако, когда вы создаете функцию, фактический код функции («тело») передается в виде строки и не анализируется той частью, которая проверяет базовый синтаксис create function. Эта строка передается «языку», который указан для дальнейшей проверки.

Параметр конфигурации check_function_bodies определяет, выполняется ли эта проверка при создании функции.

Если установлено значение off, тело не проверяется, и create function() успешно выполняется, даже если тело недопустимо.

Итак, следующее успешно создает функцию:

set check_function_bodies=off;

create function invalid()
  returns void
as
$$
begin
  update foo.bar = 'this is so wrong';
end;
$$
language plpgsql;

Я думаю, код функции, который вы видите в этой базе данных, был создан таким образом.


Допустимым вариантом использования для этого является создание функций, которые зависят друг от друга, без необходимости думать о порядке, в котором они должны быть созданы.

0 голосов
/ 17 января 2019

Это недопустимый синтаксис SQL, и postgres будет раздражен при фактическом вызове этой функции.

Увидев, что база комментариев показывает, что я не сошла с ума от смущения, я обнаружила промежуточную базу данных с установленной хранимой процедурой и попыталась вызвать предложение UPDATE, что привело к следующей ошибке:

ERROR:  syntax error at or near "="
LINE 1: UPDATE authors.author_id = (SELECT gov_id FROM authors...
                                ^
QUERY:  UPDATE authors.author_id = (SELECT gov_id FROM authors.gov_id WHERE mem_id=p_mem_id)
CONTEXT:  PL/pgSQL function authors.copy_govid(integer,integer) line 15 at SQL statement
...