我想将带有分隔符“~,~”的平面文件中的数据加载到 PostgreSQL 表中。我已经尝试如下,但看起来分隔符有限制。如果 COPY 语句不允许使用多个字符作为分隔符,是否有其他方法可以做到这一点?
metadb=# \COPY public.CME_DATA_STAGE_TRANS FROM 'E:\Infor\Outbound_Marketing\7.2.1\EM\metadata\pgtrans.log' WITH DELIMITER AS '~,~'
ERROR: COPY delimiter must be a single one-byte character
\copy: ERROR: COPY delimiter must be a single one-byte character
如果您使用 Vertica,您可以使用 E' ' 或 U&' 9'
要指示非打印分隔符(例如制表符), 指定扩展字符串语法中的字符 (E'...')。如果你的 数据库已启用 StandardConformingStrings,请使用 Unicode 字符串 文字 (U&'...')。例如,使用 E' ' 或 U&' 9' 来 指定制表符作为分隔符。
显而易见的事情就是所有其他答案所建议的。编辑导入文件。我也会这么做。
但是,作为概念证明,这里有两种方法可以实现此目的无需额外工具。
pg_read_file()
,默认情况下仅限于 超级用户。 (但请阅读手册。)
CREATE OR REPLACE FUNCTION f_import_file(OUT my_count integer)
RETURNS integer
LANGUAGE plpgsql VOLATILE AS
$func$
DECLARE
myfile text; -- read xml file into that var.
-- !pg_read_file() only accepts relative path based on database dir!
datafile text := '\path\to\file.txt';
BEGIN
myfile := pg_read_file(datafile, 0, 100000000); -- arbitrary 100 MB max.
INSERT INTO public.my_tbl
SELECT ('(' || regexp_split_to_table(replace(myfile, '~,~', ','), E'\n') || ')')::public.my_tbl;
-- !depending on file format, additional quotes may be needed to create a valid format.
GET DIAGNOSTICS my_count = ROW_COUNT;
END
$func$;
这使用了许多高级功能。
如果您可以保证“~”仅出现在分隔符“~,~”中,那么在这种特殊情况下您可以继续使用普通的
COPY
。只需将“~,~”中的“,”视为附加列,然后批量加载到与之匹配的临时表即可。CREATE TABLE foo (a int, b int, c int);
然后您可以(在一笔交易中):
CREATE TEMP TABLE foo_tmp ON COMMIT DROP (
a int, tmp1 "char"
, b int, tmp2 "char"
, c int);
COPY foo_tmp FROM '\path\to\file.txt' WITH DELIMITER AS '~';
INSERT INTO foo (a,b,c)
SELECT a,b,c FROM foo_tmp;
不幸的是,没有办法在 Postgres 中加载带有多个字符分隔符
~,~
的平面文件,除非你想以某种(很棒的)方式自己修改源代码(当然还要重新编译):
/* Only single-byte delimiter strings are supported. */
if (strlen(cstate->delim) != 1)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY delimiter must be a single one-byte character")));
你想要的是使用一些外部工具预处理你的输入文件,例如
sed
可能是GNU/Linux平台上的最佳伴侣,例如:
sed s/~,~/\\t/g inputFile
不太确定您是在寻找 postgresql 解决方案还是只是通用解决方案。
如果是我,我会打开一份 vim(或 gvim)并运行命令
:%s/~,~/~/g
您可以使用单个字符分隔符,打开
notepad
按 ctrl+h
将 ~,~
替换为不会干扰的内容。就像|