Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如何编写此pl/pgsql函数?_Postgresql_Plpgsql - Fatal编程技术网

Postgresql 如何编写此pl/pgsql函数?

Postgresql 如何编写此pl/pgsql函数?,postgresql,plpgsql,Postgresql,Plpgsql,我想编写一个存储过程,返回一个“展平”对象。通过“展平”,我基本上选择了一组行,并将行中的特定字段返回到函数返回的数据中 下面的代码解释了我要做的事情 CREATE TABLE user (id int, school_id int, name varchar(32)); CREATE TYPE my_type (user1_id int, user1_name varchar(32), user2_id int, user2_name varchar(32)); CREATE OR REP

我想编写一个存储过程,返回一个“展平”对象。通过“展平”,我基本上选择了一组行,并将行中的特定字段返回到函数返回的数据中

下面的代码解释了我要做的事情

CREATE TABLE user (id int, school_id int, name varchar(32));

CREATE TYPE my_type (user1_id int, user1_name varchar(32), user2_id int, user2_name varchar(32));

CREATE OR REPLACE FUNCTION get_two_users_from_school(schoolid int)
RETURNS my_type AS $$
DECLARE
 result my_type
 temp_result user
BEGIN
  -- for purpose of this question assume 2 rows returned
  SELECT id, name INTO temp_result FROM user where school_id = schoolid LIMIT 2;
  -- Will the (pseudo)code below work?:
  result.user1_id := temp_result[0].id ;
  result.user1_name := temp_result[0].name ;
  result.user2_id := temp_result[1].id ;
  result.user2_name := temp_result[1].name ;
  return result ;
END
$$ language plpgsql
我有两个问题:

  • 我是否为变量temp_结果使用了正确的数据类型
  • 我是否正确访问了行(使用数组索引)
我是否正确访问了行(使用数组索引)

不需要,您需要使用光标在结果中循环,这在手册中有很好的解释:

像这样的方法应该会奏效:

DECLARE temp_result RECORD; row_counter integer; BEGIN row_counter := 1; FOR temp_result IN SELECT id, name FROM user where school_id = schoolid LIMIT 2 LOOP IF row_counter = 1 THEN result.user1_id := temp_result.id; result.user1_name = temp_result.name; END IF; IF row_counter = 2 THEN result.user2_id := temp_result.id; result.user2_name = temp_result.name; END IF; row_counter := row_counter + 1; END LOOP; return result; END; 声明 临时结果记录; 行计数器整数; 开始 行计数器:=1; 对于SELECT id中的temp_结果,来自用户的名称,其中school_id=school id LIMIT 2循环 如果行\u计数器=1,则 result.user1_id:=temp_result.id; result.user1_name=temp_result.name; 如果结束; 如果行\u计数器=2,则 result.user2_id:=temp_result.id; result.user2_name=temp_result.name; 如果结束; 行计数器:=行计数器+1; 端环; 返回结果; 结束; 顺便说一句:拥有一个名为“user”的表并不是一个好主意,因为user是一个保留字,从长远来看可能会导致一些问题

我是否正确访问了行(使用数组索引)

不需要,您需要使用光标在结果中循环,这在手册中有很好的解释:

像这样的方法应该会奏效:

DECLARE temp_result RECORD; row_counter integer; BEGIN row_counter := 1; FOR temp_result IN SELECT id, name FROM user where school_id = schoolid LIMIT 2 LOOP IF row_counter = 1 THEN result.user1_id := temp_result.id; result.user1_name = temp_result.name; END IF; IF row_counter = 2 THEN result.user2_id := temp_result.id; result.user2_name = temp_result.name; END IF; row_counter := row_counter + 1; END LOOP; return result; END; 声明 临时结果记录; 行计数器整数; 开始 行计数器:=1; 对于SELECT id中的temp_结果,来自用户的名称,其中school_id=school id LIMIT 2循环 如果行\u计数器=1,则 result.user1_id:=temp_result.id; result.user1_name=temp_result.name; 如果结束; 如果行\u计数器=2,则 result.user2_id:=temp_result.id; result.user2_name=temp_result.name; 如果结束; 行计数器:=行计数器+1; 端环; 返回结果; 结束;
顺便说一句:拥有一个名为“user”的表并不是一个好主意,因为user是一个保留字,从长远来看可能会导致一些问题。

这里的表名仅用于示例:)这里的表名仅用于示例:)