首页 > 解决方案 > 如何在 for 循环中使用行字段?

问题描述

我正在尝试创建一个返回SETOF自定义类型的函数,该类型以这种方式从表中获取其内容:

桌子

CREATE table users(
  id SERIAL PRIMARY KEY,
  first_name VARCHAR(255) NOT NULL,
  last_name VARCHAR(255) NOT NULL,
  birthday DATE NOT NULL
);

INSERT INTO users(first_name, last_name, birthday) VALUES
  ('Albert', 'Albertson', '2000-01-01'),
  ('Bernard', 'Bernardson', '2001-06-24'),
  ('Carl', 'Carlson', '2007-11-03')
;

类型

CREATE TYPE User_Data AS (
  id INTEGER,
  full_name VARCHAR(510),
  age INTEGER
);

功能

CREATE OR REPLACE FUNCTION get_user_data()
RETURNS SETOF User_Data AS $func$
  DECLARE
    user users%ROWTYPE;
    data User_Data;
  BEGIN
    FOR user IN SELECT * FROM users LOOP
      data.id := user.id;
      data.full_name := user.first_name || ' ' || user.last_name;
      data.age := DATEDIFF(year, user.birthday, NOW());
      RETURN NEXT data;
    END LOOP;
    RETURN;
  END;
$func$
LANGUAGE plpgsql;

问题

ERROR:  syntax error at or near "."
LINE 8:       data.id := user.id;
                             ^

显然,该函数无法访问user变量中的字段,尽管它是users%ROWTYPE具有 id 的类型。

请注意,如果我注释掉该行,则错误报告到user.first_name下一行,表明这不是字段问题,而是user变量问题。

为什么它不起作用,我该如何解决?

标签: for-loopplpgsqlrowtype

解决方案


user是 PostgreSQL 的保留关键字——它不是好 postgres 的变量名。如果你需要它,那么可能你应该使用双引号:

data.id := "user".id;

在 plpgsql 中,任何表达式都是 SQL 表达式,所以你不能在没有转义的情况下使用 SQL 保留关键字。


推荐阅读