1

我有大约 6000 个 IPv6 地址需要加载到 postgres 表中。甚至没有找到我的“如果不存在错误”的地步,它在未转义的“:”上很糟糕,我不太了解 postgres,是否有一个 LOAD DATA INFILE 函数会在行中读取并忽略“: ' 以及查找现有记录?

INSERT INTO ip_list (ip_addr)
SELECT 'ip_addr',
 2600:3c01:e000:44:0:0:0:1,
 2600:3c01:e000:44:0:0:0:2,
 2600:3c01:e000:44:0:0:0:3,
 2600:3c01:e000:44:0:0:0:4,
 2600:3c01:e000:44:0:0:0:5,
 2600:3c01:e000:44:0:0:0:7,
....
WHERE NOT EXIST(
        SELECT 1 FROM ip_list WHERE name = 'ip_addr')
        RETURNING id
        );


ERROR:  syntax error at or near ":"
LINE 3:  2600:3c01:e000:44:0:0:0:1,

更新:

此方法从不上传任何记录:

You are now connected to database "postfix" as user "postgres".
postfix=# create temporary table t(ip_addr inet);
CREATE TABLE
postfix=# \copy t from '/var/www/localhost/htdocs/ipListScript'
postfix=# INSERT INTO ip_list(ip_addr)
select ip_addr from ip_list where
not exists (select 1 from ip_list where ip_list.ip_addr=ip_list.ip_addr);
4

2 回答 2

2

看起来你只需要在你的 IP 地址周围加上引号。查看此页面以获取更多信息:

http://www.postgresql.org/docs/9.1/static/datatype-net-types.html

于 2013-08-28T00:32:20.993 回答
1

6000 个地址作为 SQL 语句中的常量是不合理的,除了您建议的语法无论如何都不正确(VALUES需要一个子句)。

合理的方法是COPY从文件中插入临时表,然后从临时表中插入到你的最终表中,同时消除重复。

在 psql 中:

create temporary table t(ip_addr inet);

\copy t from '/path/to/file.txt'

INSERT INTO ip_list(ip_addr) 
 select ip_addr from t where
   not exists (select 1 from ip_list where ip_list.ip_addr=t.ip_addr);

\copypsql程序的命令,负责在客户端加载文件并将其提供给服务器。

如果上下文不允许使用该psql命令,您可以使用 SQL 语句COPY tablename FROM '/path/to/file.txt',但您必须以超级用户身份连接,并且该用户应该可以在服务器上访问该文件postgres
如果这些限制不可接受,您希望COPY tablename FROM STDIN通过自己的方式使用和提供数据。

于 2013-08-28T15:27:02.833 回答