6

给定架构

CREATE TABLE users (
    id bigserial PRIMARY KEY,
    email varchar(254) NOT NULL
);
CREATE UNIQUE INDEX on users (lower(email));

CREATE FUNCTION all_users() RETURNS users AS $$
    SELECT * FROM users;
$$ LANGUAGE SQL STABLE;

,不应该SELECT * FROM all_users()(假设users表为空)不返回任何行,而不是包含所有null值的行吗?

在此处查看 SQL Fiddle:http ://sqlfiddle.com/#!15/b5ba8/2

4

2 回答 2

4

那是因为您的功能被设计破坏了。它应该是:

CREATE FUNCTION all_users() RETURNS SETOF users AS
'SELECT * FROM users' LANGUAGE sql STABLE;

或者,更灵活的形式,RETURNS TABLE (...) 如 @Clodoaldo 已发布。但是RETURNS SETOF users使用SELECT * FROM users.

您的原始函数始终返回单个值(复合类型),它已以这种方式声明。如果您插入一些行,它将以更壮观的方式中断。

考虑这个SQL Fiddle 演示

为了更好地理解,您的函数调用与这个普通的 SELECT 查询相同:

SELECT (SELECT u from users u).*;

回报:

id     | email
-------+------
<NULL> | <NULL>

区别:如果子查询返回多行,普通 SQL 将引发异常,而函数将只返回第一行并丢弃其余行。

与往常一样,手册中的详细信息。

于 2014-03-27T22:42:19.600 回答
2

您的函数返回记录。所以它必须至少返回一条记录。如果您想要一个空的结果集,请返回一个表:

CREATE or replace FUNCTION all_users()
RETURNS table (id bigint, email varchar(254)) AS $$
    SELECT id, email FROM users;
$$ LANGUAGE SQL STABLE;
于 2014-03-27T22:15:20.070 回答