PostgreSQL : Frequent Function Call Error

学习 PostgreSQL 函数语法时,在调用函数时经常出现以下 ERROR,今天总结下。

调用函数常见错误

错误一

1
ERROR: a column definition list is required for functions returning "record"

错误二

1
ERROR: a column definition list is only allowed for functions returning "record"

上面具体错误原因暂时不分析,接下来针对上面 ERROR,通过实验来演示:.

错误一演示

创建测试表并插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
skytf=> create table test_result3 (id integer,name varchar(32),addr varchar(32),result varchar(32));  
CREATE TABLE
skytf=> insert into test_result3 select generate_series(1,10),'test_'|| generate_series(1,10),'no','no';
INSERT 0 10

skytf=> select * From test_result3;
id | name | addr | result
----+---------+------+--------
1 | test_1 | no | no
2 | test_2 | no | no
3 | test_3 | no | no
4 | test_4 | no | no
5 | test_5 | no | no
6 | test_6 | no | no
7 | test_7 | no | no
8 | test_8 | no | no
9 | test_9 | no | no
10 | test_10 | no | no
(10 rows)

创建函数

1
2
3
4
5
6
7
8
9
10
11
12
CREATE OR REPLACE FUNCTION skytf.func_test_result3_query ( in_id integer)  
RETURNS SETOF RECORD as
$$
DECLARE
v_rec RECORD;
BEGIN

return query select * from test_result3 where id = in_id;
return;
END;
$$
LANGUAGE PLPGSQL;

执行函数(不指定目标列)

1
2
3
skytf=> select * from func_test_result3_query(1);  
ERROR: a column definition list is required for functions returning "record"
LINE 1: select * from func_test_result3_query(1);

备注:执行函数报错,提示需要指定 definition column。

执行函数(指定目标列)

1
2
3
4
skytf=> select * from func_test_result3_query(1) t(id integer,name varchar,addr varchar,result varchar);  
id | name | addr | result
----+--------+------+--------
1 | test_1 | no | no

备注:在返回类型为 RECORD 函数,由于 RECORD 类型为不确定数据类型,在调用函数时需要指定返回类型目标列,

错误二演示

创建用户表并插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mydb=> create table test_user (id int4 primary key ,username varchar(32),pwd varchar,nickname varchar(32));  
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_user_pkey" for table "test_user"
CREATE TABLE

mydb=> insert into test_user select generate_series(1,10),'user'|| generate_series(1,10),md5(generate_series(1,10)::varchar),'no';
INSERT 0 10

mydb=> select * from test_user;
id | username | pwd | nickname
----+----------+----------------------------------+----------
1 | user1 | c4ca4238a0b923820dcc509a6f75849b | no
2 | user2 | c81e728d9d4c2f636f067f89cc14862c | no
3 | user3 | eccbc87e4b5ce2fe28308fd9f2a7baf3 | no
4 | user4 | a87ff679a2f3e71d9181a67b7542122c | no
5 | user5 | e4da3b7fbbce2345d7772b0674a318d5 | no
6 | user6 | 1679091c5a880faf6fb5e6087eb1b2dc | no
7 | user7 | 8f14e45fceea167a5a36dedd4bea2543 | no
8 | user8 | c9f0f895fb98ab9159f51fd0297e236d | no
9 | user9 | 45c48cce2e2d7fbdea1afc51c7c6ad26 | no
10 | user10 | d3d9446802a44259755d38e6d163e820 | no
(10 rows)

创建函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE OR REPLACE FUNCTION func_user_login ( in in_id integer, out o_username varchar,out o_pwd varchar )  
RETURNS SETOF RECORD as
$$
DECLARE
rec record;
BEGIN

for rec in (select id,username,pwd from test_user where id=in_id) loop
o_username :=rec.username;
o_pwd :=rec.pwd;
RETURN NEXT ;
end loop;
return;
END;
$$
LANGUAGE PLPGSQL;

调用函数(不指定目标列)

1
2
3
4
5
mydb=> select * From func_user_login(1);  
o_username | o_pwd
------------+----------------------------------
user1 | 3efe667c41640f41cb87ad24eec2ed40
(1 row)

备注:这里没有指定目标列但没有报错,这是因为在定义函数 func_user_login 时,已指明了输出参数 o_username 和 o_pwd,所以在调用函数时不需要指定目标列,下面测试下如果指定目标列会是啥子情况。

调用函数(指定目标列)

mydb=> select * From func_user_login(1) t ( username varchar, pwd varchar);  
ERROR: a column definition list is only allowed for functions returning "record"  
LINE 1: select * From func_user_login(1) t ( username varchar, pwd v...  
 ^

备注:指定目标列后,函数 func_user_login 执行报错。

总结

在PostgreSQL中调用函数时有两种情况:即需要指定目标列和不需要指定目标列,这种情况取决于函数是否指定明确输出参数,简单总结如下

  1. 如果函数指定输出参数为 “ RETURNS SETOF RECORD” ,则调用函数时需要指定目标列。
  2. 如果函数指定输出参数为 “ RETURNS SETOF datatype” ,datatype 为返回的类型,调用函数时不需要指定目标列。
  3. 如果函数中有指定的输出参数,例如 (out o_name varchar),则调用函数时不需要指定目标列。

原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/237873.html

(0)
上一篇 2022年1月29日
下一篇 2022年1月29日

相关推荐

发表回复

登录后才能评论