CREATE VIEW指定的列名称多于列

时间:2016-08-05 16:17:09

标签: sql postgresql postgresql-9.4

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

  

CREATE VIEW指定的列名称多于列。

但为什么呢? f1不会返回包含5列的表格,v1也不应该包含5列?此外,如果我从第一个SELECT语句中删除强制转换,我收到此错误消息:

  

最终语句返回未知而不是第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);

1 个答案:

答案 0 :(得分:1)

考虑一个简单的例子:

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

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

但是,如果在表上下文中调用函数,则返回类似真表的值:

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

因此,您应该在创建视图时使用第二种方法:

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