假设我有一些客户数据,如下文保存在文本文件中:
|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()
并避免首先插入不干净的数据?
谢谢,
答案 0 :(得分:1)
我在其中一个项目中有某种类似的用例。我的输入文件:
我使用以下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代码更简单。这种消毒是触发器非常简单和非常简单的事情。