模棱两可的函数参数
Posted
技术标签:
【中文标题】模棱两可的函数参数【英文标题】:Ambiguous function arguments 【发布时间】:2015-11-17 02:18:53 【问题描述】:示例函数:
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;
导致此错误:
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.
很明显,我可以通过更改参数名称来纠正这个问题。有没有替代方案?
【问题讨论】:
更改参数的名称是解决此问题的唯一明智方法。 【参考方案1】:通常,在编程中为两个不同的对象使用相同的名称是一种不好的做法。您不应该这样做,更改参数名称是最好的解决方案。然而,Postgres 敞开大门(为了与旧版本兼容)。你可以设置configuration parameter:
set plpgsql.variable_conflict to use_variable;
参数的可能值:error
(默认)、use_variable
或use_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;
或者,您可以明确限定不明确的名称,这是比上述解决方案更好的解决方案。限定名称的形状为<function_name>.<parameter_name>
,例如update_a_table.id
。
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;
【讨论】:
我很抱歉,但禁用 variable_conflict 不是一个好主意(不是没有强烈警告)。解决方案应该始终使用限定名称。 @PavelStehule - 谢谢,我已经添加了两个词。 第二种解决方案对我不起作用。错误:缺少表“update_a_table”的 FROM 子句条目 @DominikK - 使用示例数据和您的查询提出问题。您可以使用SqlFiddle 来显示问题。 @EleanorHolley - 这是一个误解。限定名称中没有<schema_name>
,您应该改用<function_name>
。查看更新后的答案。【参考方案2】:
对于极难检测到的错误,此错误更安全。 PLpgSQL 好的风格需要
在任何嵌入式 SQL 中随处使用限定名称 - 访问函数参数时使用模式 function_name.parameter_name
以前的 Postgres 版本没有这种检测,只有一种保护是使用带有特殊前缀的变量。通常使用'_'作为前缀。规则很简单 - 当您的函数包含嵌入式 SQL 时,所有变量和参数名称都应以“_”开头。这样可以更安全地防止名称冲突并提高可读性,因为您可以快速了解什么是变量以及什么是 SQL 标识符。
【讨论】:
恐怕不太明白。我在哪里可以找到有关特殊前缀的信息?什么是嵌入式 SQL? 前缀 '_' 并不特殊 - 它通常用于 - postgres.cz/wiki/PL/… 。许多建议与 Oracle 的 PL/SQL 共享。嵌入式 SQL 是在 PLpgSQL 中用作第一类对象(语言的组成部分)的任何 SQL 语句。【参考方案3】:CREATE OR REPLACE FUNCTION update_a_table_1(int,text)
RETURNS void AS $$
BEGIN
UPDATE a_table
SET name = $2
WHERE id =$1;
END;
$$ LANGUAGE plpgsql;
您可以在您的 如果你有 2 个 args,所以你只需要通过提供它来访问它们 索引(
$1
和$2
)但是当你有很多时,IMO 这不是一个好主意 要传递的参数(例如一个具有 10 或 10+ 个参数的函数,它可能 把你弄糊涂了)
【讨论】:
以上是关于模棱两可的函数参数的主要内容,如果未能解决你的问题,请参考以下文章