【问题标题】:plpgsql Select statement in For loop to create multiple CSV filesFor循环中的plpgsql Select语句创建多个CSV文件
【发布时间】:2013-12-26 21:16:09
【问题描述】:

我想重复以下查询 8760 次,将“2”替换为 1 到 8760 一年中的每个小时。我们的想法是为每个小时创建一个单独的 CSV 文件以供进一步处理。

COPY 
(SELECT *
FROM 
  public.completedsolarirad2012
WHERE 
  completedsolarirad2012."UniquetmstmpID" = 2)
TO 'C:\temp\2012hour2.csv' WITH DELIMITER ','
CSV HEADER

我整理了以下功能(仅用了几个小时进行了测试):

CREATE OR REPLACE FUNCTION everyhour()
  RETURNS void AS
$BODY$BEGIN
FOR i IN 0..5 LOOP
  EXECUTE $x$ 
  COPY (
    SELECT *
    FROM 
    public.completedsolarirad2012
    WHERE 
    completedsolarirad2012."UniquetmstmpID" = i
    )
   TO $concat$ 'C:\temp.' || i::text 
         || '.out.csv' WITH DELIMITER ',' CSV HEADER $concat$
    $x$;
END LOOP;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION everyhour()
  OWNER TO postgres;

我似乎有两个不同的问题:

首先,我得到:

错误:“i”列不存在。

其次,当我仅通过将“i”替换为 e.g. 来测试连接语句时“2”,我得到:

错误:不允许 COPY 到文件的相对路径

我是 postgres 超级用户,所以我不明白我为什么会遇到这个问题。

注意:删除连接语句周围的 $concat$ 双引号会导致以下错误:

ERROR:  syntax error at or near "||"
LINE 9:    TO 'C:\temp.' || i::text

如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 由于我们处理的是文件系统,所以您需要提供服务器的操作系统。看起来像窗户。而且您总是需要提供正在使用的 Postgres 版本。

标签: postgresql csv plpgsql pgadmin


【解决方案1】:

假设您的服务器操作系统是 Windows。

CREATE OR REPLACE FUNCTION everyhour()
  RETURNS void AS
$func$
BEGIN
FOR i IN 0..5 LOOP
   EXECUTE '
   COPY (
      SELECT *
      FROM   public.completedsolarirad2012 c
      WHERE  c."UniquetmstmpID" = ' || i || $x$)
   TO 'C:/temp.'$x$ || i || $x$'.out.csv' WITH DELIMITER ',' CSV HEADER$x$;
END LOOP;
END
$func$  LANGUAGE plpgsql;

format() 更简单

从 Postgres 9.1 开始,您可以使用 format() 来简化复杂的连接:

CREATE OR REPLACE FUNCTION everyhour()
  RETURNS void AS
$func$
BEGIN
FOR i IN 0..5 LOOP
   EXECUTE format($x$COPY (
   SELECT *
   FROM   public.completedsolarirad2012 c
   WHERE  c."UniquetmstmpID" = %1$s)
   TO 'C:/temp.%1$s.out.csv' WITH DELIMITER ',' CSV HEADER$x$, i);
END LOOP;
END
$func$  LANGUAGE plpgsql;

【讨论】:

  • format() 效果很好 - 非常感谢。但是,我仍然遇到连接问题:错误:“||”处或附近的语法错误第 9 行:到 'C:/temp/' ||我::文本。 Format() 解决了我的问题,但我真的很想弄清楚我在串联方面做错了什么,以供将来参考。抱歉,我应该说我使用的是 OS Windows 7 PostgreSQL 9.3。以后我会适当地提供细节。
  • @DianePalmer:抱歉,我的第一个版本缺少引号。现在应该修好了。
猜你喜欢
  • 1970-01-01
  • 2019-10-30
  • 2019-02-23
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
  • 2019-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多