示例函数:
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.
很明显,我可以通过更改参数的名称来纠正这个问题。有没有替代方案?
答案 0 :(得分:10)
通常,在编程中使用两个不同对象的相同名称是不好的做法。你不应该这样做,更改参数名称是最好的解决方案。但是,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;
或者,您可以明确限定模糊名称,这是一个比上述更好的解决方案:
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;
答案 1 :(得分:3)
此错误对于非常困难的可检测错误更安全。 PLpgSQL的好风格需要
在任何嵌入式SQL中使用限定名称 - 访问函数的参数使用模式by_name_list = read_countries('countries.txt')
by_area_list = list(by_name_list) # a shallow copy of the list
by_name_list.sort(key=lambda i: i[0]) # sort by name
by_area_list.sort(key=lambda i: i[1]) # sort by area
for k in xrange(len(by_name_list)):
country_name = by_name_list[k][0]
if by_area_list[k][0] == country_name:
print 'Same order: %s in position %d'%(country_name, k)
以前版本的Postgres没有进行此检测,只有一种保护使用带有特殊前缀的变量。通常用于' _'作为前缀。规则很简单 - 当您的函数包含嵌入式SQL时,所有变量和参数名称都应以' _'开头。这对于名称冲突更安全,并且增加了可读性,因为您可以快速查看什么是变量以及什么是SQL标识符。
答案 2 :(得分:1)
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并不是一个好主意 args传递(例如一个具有10或10+ args的函数 迷惑你)