gpt4 book ai didi

postgresql - 将 CSV 文件中的内容加载到 PostgreSQL 表中

转载 作者:行者123 更新时间:2023-11-29 13:04:59 25 4
gpt4 key购买 nike

下面描述了我尝试将文件中的数据加载到运行在 Linux RedHat 7.2 主机上的 PostgreSQL 8.0 数据库中的过程。

现在,我的问题是 FOR EVERY ROW 触发器被调用并且程序正在执行。

然而,我希望它做的是在我输入文件名后让它检查表中的相应行,并根据记录的内容决定是否执行 DUMP BULK DATA DUMP WHOLE CSV FILE 仅一次(在触发器上)。

请帮我解决这个问题...

我的logfile.tmp如下:

27/Apr/2013:17:03:42 +0530#192.168.1.3#16#0@#$http://localhost/images/
banner-left.jpg@#$10.1ff.ff.ff#-#Y#-
27/Apr/2013:17:03:42 +0530#192.168.1.3#16#0@#$http://localhost/images/
banner-left.jpg@#$10.ff.ff.2ff05#-#Y#-

我正在使用的 COPY 命令:

/usr/local/pgsql/bin/psql localhost -d d1 -U u1 -tc "COPY tblaccesslog ( accesstime, clientip, username, request,bytes, urlpath, url, contenttype, issite, webcatname)  FROM 'logfile.tmp' WITH DELIMITER AS '#';" >> /tmp/parselog.log 2>&1

有问题的触发器(insert_accesslog_trigger):

insert_accesslog_trigger BEFORE INSERT ON tblaccesslog FOR EACH ROW EXECUTE PROCEDURE accesslog_insert_trigger()

最后是使用的触发函数(accesslog_insert_trigger()):

accesslog_insert_trigger()
DECLARE
tablemaxtuples NUMERIC(10);
tableno NUMERIC(10);
newtable TEXT;
query TEXT;
tablecount NUMERIC(10);
min_limit NUMERIC(10);
max_limit NUMERIC(10);
BEGIN

tablemaxtuples := 100000;
tableno := ( NEW.id - ( NEW.id % tablemaxtuples ) ) / tablemaxtuples +1;
newtable := 'tblaccesslog'||to_char(CURRENT_DATE,'YYYYMMDD')||'_child_'||tableno;

SELECT trim(count(tablename)) INTO tablecount FROM pg_tables WHERE tablename=newtable ;
IF tablecount = 0
THEN
min_limit := (tableno-1)*tablemaxtuples;
max_limit := min_limit + tablemaxtuples;
query := 'CREATE TABLE '||newtable||'( PRIMARY KEY (id),CHECK ( id >= '||min_limit||' AND id <'||max_limit||' ) ) INHERITS (tblaccesslog)';
EXECUTE query;
END IF;

query := 'INSERT INTO '|| newtable ||' ( id, username, clientip, url, accesstime, requestbytes, contenttype, issite, urlpath, webcatname ) VALUES ('||NEW.id||','''||NEW.username||''','''||NEW.clientip||''','''||NEW.url||''','''||NEW.accesstime||''','''||NEW.requestbytes||''','''||NEW.contenttype||''','''||NEW.issite||''','''|| replace(NEW.urlpath,'\'','') ||''','''||NEW.webcatname||''')';
EXECUTE query;
RETURN NULL;

END;

最佳答案

PostgreSQL documentation overview of triggers明确表示没有适合您要求的触发器类型:正如其名称所示,FOR EACH ROW 触发器将为每一行执行一次,正如手册页所述“语句级触发器目前没有任何方法来检查语句修改的单个行。”

但是,您可以将实际的 COPY 命令放入一个函数中。该函数可以COPY TO 一个临时表,然后执行适当的步骤来确定它应该从那里去哪里。

然后你的复制命令(我猜是在 cron 作业或类似的)将只运行 SELECT bulk_insert_access_log(); 而不是当前列出的长行.

关于postgresql - 将 CSV 文件中的内容加载到 PostgreSQL 表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16251980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com