CREATE VIEW 指定的列名多于列

CREATE VIEW specifies more column names than columns

如果我 运行 在 PostgreSQL 9.4.8 中执行以下语句,我会收到此错误消息:

CREATE VIEW specifies more column names than columns.

但是为什么呢? f1 return 不是有 5 列的 table 并且 v1 不应该也有 5 列吗?此外,如果我从第一个 SELECT 语句中删除强制转换,我会收到此错误消息:

Final statement returns unknown instead of character varying at column 1.

但是为什么呢?正确的类型 VARCHAR(20) 是从 RETURNS 得知的,那么为什么没有像 'a' 这样的字符串的隐式转换?

CREATE OR REPLACE FUNCTION f1 (a1 INTEGER, a2 INTEGER)
RETURNS TABLE (c1 VARCHAR(20), c2 VARCHAR(20), c3 INTEGER, c4 VARCHAR(20), c5 VARCHAR(128))
AS $$
SELECT 'a'::VARCHAR(20), 'b'::VARCHAR(20), 1::INTEGER, 'c'::VARCHAR(20), 'd'::VARCHAR(128);
$$ LANGUAGE SQL;

CREATE VIEW v1 (c1, c2, c3, c4, c5)
AS SELECT f1 (1, 2);

考虑这个简单的例子:

postgres=# create function foofunc() returns table(a int, b text) language sql as $$ select 1, 'a'::text $$;
postgres=# select foofunc();
╔═════════╗
║ foofunc ║
╠═════════╣
║ (1,a)   ║
╚═════════╝

当函数在 column/variable 上下文中调用时,它 returns 指定返回类型的单个值。这是错误的来源:视图的 select returns 只有一列。

但是,如果函数在 table 上下文中调用,那么它 returns 的值就像一个真实的 table:

postgres=# select * from foofunc();
╔═══╤═══╗
║ a │ b ║
╠═══╪═══╣
║ 1 │ a ║
╚═══╧═══╝

所以你应该在创建视图时使用第二种方法:

CREATE VIEW v1 (c1, c2, c3, c4, c5) AS
  SELECT * FROM f1 (1, 2);