将PostgreSQL数据库的PL/pgSQL输出保存到CSV文件的最简单方法是什么?

我正在使用PostgreSQL 8.4和pgAdmin III以及PSQL插件来运行查询.

推荐答案

您希望生成的文件在服务器上还是在客户端上?

Server side

如果您想要一些易于重用或自动化的东西,可以使用Postgresql的内置COPY命令.例如

Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;

This approach runs entirely on the remote server-它无法写入本地PC.它还需要作为Postgres"超级用户"(通常称为"root")运行,因为Postgres无法阻止它在该机器的本地文件系统中做一些令人讨厌的事情.

这实际上并不意味着你必须以超级用户的身份连接(自动化这将是另一种安全风险),因为你可以使用the SECURITY DEFINER option to CREATE FUNCTION来创建一个runs as though you were a superuser的函数.

关键的一点是,你的函数可以执行额外的判断,而不仅仅是绕过安全性——因此你可以编写一个函数来导出你需要的确切数据,或者你可以编写一个可以接受各种选项的东西,只要它们符合严格的白名单.你需要判断两件事:

  1. 应该允许用户在磁盘上读/写哪files个?例如,这可能是一个特定的目录,文件名可能必须有一个合适的前缀或扩展名.
  2. 用户应该能够在数据库中读/写哪个tables?这通常由数据库中的GRANT来定义,但该函数现在以超级用户的身份运行,因此通常"超出范围"的表将完全可访问.您可能不想让别人调用您的函数,并在"users"表的末尾添加行…

我已经写了a blog post expanding on this approach个,包括一些导出(或导入)满足严格条件的文件和表的函数示例.


Client side

另一种方法是do the file handling on the client side,即在应用程序或脚本中.Postgres服务器不需要知道您要复制到哪个文件,它只需吐出数据,然后客户端将其放在某个地方.

它的基本语法是COPY TO STDOUT命令,像pgAdmin这样的图形工具将把它包装在一个漂亮的对话框中.

100 command-line client有一个名为101的特殊"元命令",它采用与"真实"COPY相同的所有选项,但在客户端内部运行:

\copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER

请注意,没有终止;,因为元命令是通过换行符终止的,与SQL命令不同.

the docs开始:

不要将COPY与psql指令\COPY混淆.\copy调用copy FROM STDIN或copy TO STDOUT,然后将数据获取/存储在psql客户端可访问的文件中.因此,使用\copy时,文件可访问性和访问权限取决于客户端而不是服务器.

应用程序编程语言may也支持推送或获取数据,但通常不能在标准SQL语句中使用COPY FROM STDIN/TO STDOUT,因为无法连接输入/输出流.PHP的PostgreSQL处理程序(not PDO)包含非常基本的pg_copy_frompg_copy_to个函数,它们在PHP数组中进行复制,这对于大型数据集来说可能效率不高.

Sql相关问答推荐

如何解决Error:operator is not unique:unknown—unknown在一个动态SQL查询?""""

用于平均多个数据并与一个数据点进行比较以判断偏移量的SQL查询

Postgres:对包含数字的字符串列表进行排序

如何利用单列历史SQLsnowflake获得合并结果

PostgreSQL使用SQL子查询在时间间隔内 Select 数据

在SQL中返回缺省值,即使查询不返回任何结果

使用SQL创建列出两个时间戳之间小时数的列

在Power Bi中将SQL代码转换为DAX

如何根据 SQL Server 中 1 条语句中 SELECT 的结果进行 INSERT 或 UPDATE

如何在sparksql查询中使用日期值?

一次 Select 语句中按组累计的SQL累计数

获取记录的上一个值,并将其与当前值一起显示

try 将多行折叠为单个结果

强制 SQL 始终通过 R 从视图中返回至少一行

如何 Select 一列具有最小值而另一列具有给定值的记录?

添加一列并根据其他列值进行填充

SQL Select 最大并获取列名

面对来自以下两个代码的不同输出

BigQuery - 将 TIMESTAMP 转换为 HH:MM:SS,然后识别 TIME_DIFF

如何根据 ID 和指标从 2 个表中找到不同的值?