PostgreSQL:如何在复制之前修改文本

时间:2013-05-31 04:41:27

标签: postgresql

假设我有一些客户数据,如下文保存在文本文件中:

|Mr   |Peter   |Bradley   |72 Milton Rise   |Keynes    |MK41 2HQ   |
|Mr   |Kevin   |Carney    |43 Glen Way      |Lincoln   |LI2 7RD    | 786 3454

我使用以下命令将上述数据复制到我的customer表中:

\copy customer(title, fname, lname, addressline, town, zipcode, phone) from 'customer.txt' delimiter '|'

然而,事实证明,在数据的各个部分之前和之后都有一些额外的空格字符。我想做的是在将数据复制到表格之前调用trim() - 实现此目的的最佳方法是什么?

有没有办法在每行的每个值上调用trim()并避免首先插入不干净的数据?

谢谢,

2 个答案:

答案 0 :(得分:1)

我在其中一个项目中有某种类似的用例。我的输入文件:

  • 将文件中的行数作为最后一行;
  • 需要在每一行添加行号;
  • 需要将file_id添加到每一行。

我使用以下shell代码:

FACT=$( dosql "TRUNCATE tab_raw RESTART IDENTITY;
COPY tab_raw(file_id,lnum,bnum,bname,a_day,a_month,a_year,a_time,etype,a_value)
 FROM stdin WITH (DELIMITER '|', ENCODING 'latin1', NULL '');
$(sed -e '$d' -e '=' "$FILE"|sed -e 'N;s/\n/|/' -e 's/^/'$DSID'|/')
\.
VACUUM ANALYZE tab_raw;
SELECT count(*) FROM tab_raw;
" | sed -e 's/^[ ]*//' -e '/^$/d'
)

dosql是一个shell函数,它使用正确的连接信息执行psql并执行作为参数给出的所有内容。

作为此操作的结果,我将$FACT变量保存插入记录的总数(用于错误检测)。

稍后我再做一次dosql电话:

dosql "SET work_mem TO '800MB';
SELECT tab_prepare($DSID);
VACUUM ANALYZE tab_raw;
SELECT tab_duplicates($DSID);
SELECT tab_dst($DSID);
SELECT tab_gaps($DSID);
SELECT tab($DSID);"

分析并将数据从辅助数据移入最终表格。

答案 1 :(得分:0)

我认为解决此问题的最佳方法是在您要插入的表中添加BEFORE INSERT触发器。这样,您可以编写一个存储过程,该存储过程将在插入每个记录之前执行,并在需要它的任何列上修剪whitepsace(或执行您可能需要的任何其他转换)。完成后,只需删除触发器(或保留它,如果您不希望在这些列中使用该空格,这将提高数据完整性)。我想解释如何在PostgreSQL中创建触发器和存储过程可能超出了这个问题的范围,但是我将链接到每个文档的文档。

我认为这是最好的方法,因为它比解析文本文件或编写shell代码更简单。这种消毒是触发器非常简单和非常简单的事情。

Creating a Trigger

Creating a Trigger Function