"missing FROM-clause entry" 在 PLPGSQL 函数中更新 table
"missing FROM-clause entry" in PLPGSQL function to update a table
我正在尝试更新 Postgres 中的 table,但出现以下错误。
Userid
是主键。
CREATE OR REPLACE FUNCTION public.update_user(username character varying,
userid character varying,
roleid integer,
deptid integer,
status integer)
RETURNS integer AS
$$
BEGIN
UPDATE public."M_User" SET public."M_User".user_name = public.update_user.username,
public."M_User".user_role_id = public.update_user.roleid,
public."M_User".dept_id = public.update_user.deptid,
public."M_User".status = public.update_user.status
WHERE public."M_User".user_id = userid;
RETURN 0;
END
$$
LANGUAGE 'plpgsql';
通话:
SELECT * FROM public.update_user ('ji','gis', 123, 24, 1);
错误:
ERROR: missing FROM-clause entry for table "update_user"
LINE 1: ...E public."M_User" SET public."M_User".user_name = public.upd...
^
QUERY: UPDATE public."M_User" SET public."M_User".user_name = public.update_user.username,
public."M_User".user_role_id = public.update_user.roleid,
public."M_User".dept_id = public.update_user.deptid,
public."M_User".status = public.update_user.status
WHERE public."M_User".user_id = userid
CONTEXT: PL/pgSQL function update_user(character varying,character varying,integer,integer,integer) line 4 at SQL
statement
SQL state: 42P01
如何解决这个问题?
doc 表示可以将输入引用为 function_name.parameter_name
,因此请尝试删除对 schema_name
的引用
UPDATE public."M_User"
SET user_name = update_user.username,
user_role_id = update_user.roleid,
dept_id = update_user.deptid,
status = update_user.status
WHERE user_id = update_user.userid;
CREATE OR REPLACE FUNCTION public.update_user(_username varchar,
_userid varchar,
_roleid integer,
_deptid integer,
_status integer)
RETURNS integer
LANGUAGE sql AS
$func$
UPDATE public."M_User" u
SET user_name = _username
, user_role_id = _roleid
, dept_id = _deptid
, status = _status
WHERE u.user_id = _userid
AND (u.user_name, u.user_role_id, u.dept_id, u.status) IS DISTINCT FROM
( _username , _roleid , _deptid , _status) -- optional addition
RETURNING u.user_id;
$func$
您 可以 使用要消除歧义的函数名称限定函数参数,但这通常是一个笨拙的解决方案。重命名函数时中断。还有其他方法。参见:
- PL/pgSQL column name the same as variable
我喜欢在参数和变量前加上下划线,而从不对列名做同样的事情。不是标准,而是一个广泛的惯例。养成 table 限定所有列名的习惯,这样就安全了。 table 别名有助于降低噪音。 the manual on UPDATE
.
中的基础知识
但是 UPDATE
语句中的目标列无法限定。 (他们从不模棱两可。)
我添加了一个可选的谓词以跳过更新,如果它不会改变任何东西的话。参见:
- How do I (or can I) SELECT DISTINCT on multiple columns?
您不需要 PL/pgSQL。 (虽然你 可以 ,当然。)一个更简单的 SQL 函数可以完成这项工作。参见:
- Difference between language sql and language plpgsql in PostgreSQL functions
RETURN 0
没有任何用处。我将其更改为 return 更新行的有效 user_id
。 (通常与输入 _userid
相同,但它可能与触发器不同。)重要的区别:如果一行实际更新,您只会获得 return 值,这使其很有用。否则,您不妨将函数声明为 RETURNS void
。与无条件 RETURN 0;
一样有用,但更便宜。
我正在尝试更新 Postgres 中的 table,但出现以下错误。
Userid
是主键。
CREATE OR REPLACE FUNCTION public.update_user(username character varying,
userid character varying,
roleid integer,
deptid integer,
status integer)
RETURNS integer AS
$$
BEGIN
UPDATE public."M_User" SET public."M_User".user_name = public.update_user.username,
public."M_User".user_role_id = public.update_user.roleid,
public."M_User".dept_id = public.update_user.deptid,
public."M_User".status = public.update_user.status
WHERE public."M_User".user_id = userid;
RETURN 0;
END
$$
LANGUAGE 'plpgsql';
通话:
SELECT * FROM public.update_user ('ji','gis', 123, 24, 1);
错误:
ERROR: missing FROM-clause entry for table "update_user" LINE 1: ...E public."M_User" SET public."M_User".user_name = public.upd... ^ QUERY: UPDATE public."M_User" SET public."M_User".user_name = public.update_user.username, public."M_User".user_role_id = public.update_user.roleid, public."M_User".dept_id = public.update_user.deptid, public."M_User".status = public.update_user.status WHERE public."M_User".user_id = userid CONTEXT: PL/pgSQL function update_user(character varying,character varying,integer,integer,integer) line 4 at SQL
statement SQL state: 42P01
如何解决这个问题?
doc 表示可以将输入引用为 function_name.parameter_name
,因此请尝试删除对 schema_name
UPDATE public."M_User"
SET user_name = update_user.username,
user_role_id = update_user.roleid,
dept_id = update_user.deptid,
status = update_user.status
WHERE user_id = update_user.userid;
CREATE OR REPLACE FUNCTION public.update_user(_username varchar,
_userid varchar,
_roleid integer,
_deptid integer,
_status integer)
RETURNS integer
LANGUAGE sql AS
$func$
UPDATE public."M_User" u
SET user_name = _username
, user_role_id = _roleid
, dept_id = _deptid
, status = _status
WHERE u.user_id = _userid
AND (u.user_name, u.user_role_id, u.dept_id, u.status) IS DISTINCT FROM
( _username , _roleid , _deptid , _status) -- optional addition
RETURNING u.user_id;
$func$
您 可以 使用要消除歧义的函数名称限定函数参数,但这通常是一个笨拙的解决方案。重命名函数时中断。还有其他方法。参见:
- PL/pgSQL column name the same as variable
我喜欢在参数和变量前加上下划线,而从不对列名做同样的事情。不是标准,而是一个广泛的惯例。养成 table 限定所有列名的习惯,这样就安全了。 table 别名有助于降低噪音。 the manual on UPDATE
.
但是 UPDATE
语句中的目标列无法限定。 (他们从不模棱两可。)
我添加了一个可选的谓词以跳过更新,如果它不会改变任何东西的话。参见:
- How do I (or can I) SELECT DISTINCT on multiple columns?
您不需要 PL/pgSQL。 (虽然你 可以 ,当然。)一个更简单的 SQL 函数可以完成这项工作。参见:
- Difference between language sql and language plpgsql in PostgreSQL functions
RETURN 0
没有任何用处。我将其更改为 return 更新行的有效 user_id
。 (通常与输入 _userid
相同,但它可能与触发器不同。)重要的区别:如果一行实际更新,您只会获得 return 值,这使其很有用。否则,您不妨将函数声明为 RETURNS void
。与无条件 RETURN 0;
一样有用,但更便宜。