我需要帮助来了解我在审核的旧系统中发现的此存储过程。特别是,我无法理解IF条件UPDATE authors.author_id ...
中的UPDATE命令。
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;
我发现这很令人困惑,因为在我的PSQL版本(无SET和直接赋值)中,此更新语句似乎不受语法支持[1],并且在数据库中没有称为authors.author_id
的关系(pg_proc中也没有)。
my_database=# \d authors.author_id;
Did not find any relation named "authors.author_id".
答案 0 :(得分:1)
正如其他人指出的那样,这是无效的语法。
但是,当您创建函数时,实际的函数代码(“主体”)将作为字符串传递,并且不会由检查基本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;
我猜您在该数据库中看到的功能代码就是用这种方式创建的。
一个有效的用例是创建相互依赖的函数,而不必考虑创建它们的顺序。
答案 1 :(得分:0)
这是无效的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