如何让postgresql从子选择中解释列名?
我在x86_64-apple-darwin14.1.0上的PostgreSQL 9.4.1中有以下查询,由apple LLVM版本6.0(clang-600.0.54)(基于LLVM 3.5svn)编译,64位 这将为dogs表中的每一行生成一次以下输出:如何让postgresql从子选择中解释列名?,sql,postgresql,Sql,Postgresql,我在x86_64-apple-darwin14.1.0上的PostgreSQL 9.4.1中有以下查询,由apple LLVM版本6.0(clang-600.0.54)(基于LLVM 3.5svn)编译,64位 这将为dogs表中的每一行生成一次以下输出: dog.id, dog.created_date, dog.updated_date, dog.author_id, dog.mother_id, dog.start_date, dog.end_date, dog.session_type_
dog.id, dog.created_date, dog.updated_date, dog.author_id, dog.mother_id, dog.start_date, dog.end_date, dog.session_type_id, dog.note, dog.cancelled, dog.life_phase
但问题是外部select查询没有取消对列名的引用并将其解释为列名,而是标记了列字符串_agg,并为dog表中的每一行吐出一次列名
如何获取postgresql以确保生成列名的内部select被外部select正确解释?您正在尝试执行动态SQL。您需要一个plpgsql函数来实现这一点。例如:
create or replace function select_dogs()
returns setof dog language plpgsql as $$
declare
list_of_columns text;
begin
SELECT string_agg(trim(cols::text, '()'), ', ')
INTO list_of_columns
FROM (
SELECT 'dog.' || column_name
FROM information_schema.columns
WHERE table_name='dog'
) AS cols;
return query execute format (
'select %s from dog', list_of_columns);
end $$;
select * from select_dogs();
阅读文档中的详细信息:。您需要使用动态SQL。内部查询只有一列,它是字符串值(包含以逗号分隔的列名列表)。SQL语句中不能有动态列。SELECT语句的列数和列名需要在编译时知道。谢谢。我现在看到的关于plpgsql的唯一问题是,尽管我费尽心机指定了完全限定的列名,但结果集已经去掉了列名中的teble前缀和句点分隔符,因此所有这些工作基本上都是无用的。有什么方法可以确保保留这些完全限定的列名吗?@DavidWatson:如果您想从表中选择所有列,那么为什么不直接使用
select*
,省去编写无法返回任何不同的函数的所有开销呢。函数的编写方式过于复杂:select*from dog
@a_horse_和_no_name这是一个更大的查询管道的一部分,在这个管道中,由于许多连接,列的消歧是一个问题,我需要输出中的所有列,并且我了解成本。事实上,我很惊讶这不是一个已解决的问题。从可用性的角度来看,当查询中有多个表时,完全限定的列将是一件有用的事情。但我意识到,不幸的是,可用性在大多数数据库内部专家的优先列表中并不是很高。@DavidWatson-我担心你想要实现的目标(在前面的问题中)是不可能的。我只能想象客户端的解决方案,正如Daniel Vérité所建议的那样。@DavidWatson:为什么不创建一个视图,为您的列指定正确的名称呢?或者给他们起个更好的名字。我已经使用关系数据库30多年了,我从来没有遇到过需要这样的情况。
create or replace function select_dogs()
returns setof dog language plpgsql as $$
declare
list_of_columns text;
begin
SELECT string_agg(trim(cols::text, '()'), ', ')
INTO list_of_columns
FROM (
SELECT 'dog.' || column_name
FROM information_schema.columns
WHERE table_name='dog'
) AS cols;
return query execute format (
'select %s from dog', list_of_columns);
end $$;
select * from select_dogs();