模糊函数参数

mar*_*asz 5 postgresql plpgsql

示例函数:

CREATE OR REPLACE FUNCTION update_a_table(id int, name text)
RETURNS void AS $$
BEGIN
    UPDATE a_table 
    SET name = name
    WHERE id = id;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

导致此错误:

ERROR:  column reference "name" is ambiguous
LINE 2:   SET name = name
                     ^
DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
Run Code Online (Sandbox Code Playgroud)

很明显,我可以通过更改参数的名称来纠正这个问题.有没有替代解决方案?

kli*_*lin 10

通常,在编程中使用两个不同对象的相同名称是不好的做法.你不应该这样做,更改参数名称是最好的解决方案.但是,Postgres打开了门(为了与旧版本兼容).您可以设置配置参数:

set plpgsql.variable_conflict to use_variable;
Run Code Online (Sandbox Code Playgroud)

参数的可能值:( error默认值)use_variableuse_column.

也可以仅为给定函数设置参数:

CREATE OR REPLACE FUNCTION update_a_table(id int, name text)
RETURNS void AS $$
#variable_conflict use_variable
BEGIN
    UPDATE a_table 
    SET name = name
    WHERE id = id;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

或者,您可以明确限定模糊名称,什么是比上面更好的解决方案:

CREATE OR REPLACE FUNCTION update_a_table(id int, name text)
RETURNS void AS $$
BEGIN
    UPDATE a_table 
    SET name = update_a_table.name
    WHERE a_table.id = update_a_table.id;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

  • 对不起,但是禁用variable_conflict并不是一个好主意(不是没有STRONG WARNING).解决方案应始终使用限定名称. (2认同)
  • @EleanorHolley - 这是一个误解。限定名称中没有“<schema_name>”,您应该使用“<function_name>”代替。查看更新的答案。 (2认同)

Pav*_*ule 6

这个错误对于非常难以检测的错误更安全。PLpgSQL 的好风格需要

  1. 在任何嵌入式 SQL 中随处使用限定名称 - 使用模式访问函数参数 function_name.parameter_name

  2. 以前版本的 Postgres 没有这种检测,只有一种保护是使用带有特殊前缀的变量。通常使用'_'作为前缀。规则很简单——当您的函数包含嵌入式 SQL 时,所有变量和参数名称都应以“_”开头。这对于名称冲突更安全,并且增加了可读性,因为您可以快速查看什么是变量以及什么是 SQL 标识符。