当返回类型是表名时,为啥 PostgreSQL 函数返回空列而不是没有行?
Posted
技术标签:
【中文标题】当返回类型是表名时,为啥 PostgreSQL 函数返回空列而不是没有行?【英文标题】:Why do PostgreSQL functions return null columns instead of no rows when the return type is a table name?当返回类型是表名时,为什么 PostgreSQL 函数返回空列而不是没有行? 【发布时间】:2020-02-14 08:04:30 【问题描述】:如果我创建一个函数f
来查询一个函数,我认为如果返回类型是表的名称而不是RETURNS TABLE(id integer, name text)
,那么它会更容易阅读。
CREATE TABLE users ( id integer, name text );
CREATE OR REPLACE FUNCTION f()
RETURNS users
AS $$
SELECT * FROM users
WHERE FALSE
$$
LANGUAGE SQL;
但是当函数中的查询返回零行时,我得到了奇怪的结果。
SELECT * FROM f();
预期结果
+------+--------+
| id | name |
|------+--------|
+------+--------+
实际结果
+--------+--------+
| id | name |
|--------+--------|
| <null> | <null> |
+--------+--------+
如果有更多列,它们仍然都是null
。如果函数中的查询返回任何行,则它按预期工作。如果我使用 RETURNS TABLE(...)
语法,我不会出现这种行为。
有没有办法解决这个问题?
我使用的是 PostgreSQL 9.6
【问题讨论】:
【参考方案1】:这与返回类型无关,但与您将函数声明为返回单行这一事实有关。
替换
RETURNS users
与
RETURNS SETOF users
您的功能将按预期工作。
与您的函数一样,如果查询没有结果,它将返回 NULL,如果查询有多个结果行,它将返回第一行。
【讨论】:
以上是关于当返回类型是表名时,为啥 PostgreSQL 函数返回空列而不是没有行?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Identity - 将用户 ID 主键默认类型从字符串更改为 int 以及使用自定义表名时出错