基于TXT文件更新表中的行(updating table rows based on txt fil

2019-08-17 23:33发布

我一直在寻找,但到目前为止,我只找到如何插入日期到基于一个CSV文件中的表格。

我有以下情形:

目录名= ticketID

在这个目录里我有几个文件,像:

  • Description.txt
  • Summary.txt -包含票头和已succefully进口。
  • Progress_#.txt -这是每次一票被udpdated。 我得到一个新的文件。
  • Solution.txt

导入Issue.txt很简单,因为这实际上是一个CSV。

现在我的问题是描述和进展的文件。

我需要从这个文件中的数据以更新现有行。 对东西的行

update table_ticket set table_ticket.description = Description.txt where ticket_number = directoryname

我使用PostgreSQL和COPY命令的有效期为新的数据,它仍然会失败是由于”; /特殊字符。

我想做到这一点使用bash脚本,但似乎它都将是不可能的:

for i in `find . -type d`
do
  update table_ticket 
  set table_ticket.description = $i/Description.txt
  where ticket_number = $i
done

当然,上面的代码将考虑到数据库的连接。

任何人对我怎么能做到这一点使用shell脚本的想法。 或者会是更好的只是使一些在Java和读取和更新记录,但我想避免这种方法。

感谢亚历克斯

Answer 1:

感谢您的回答,但我碰到这样的:

psql -U dbuser -h dbhost db 
\set content = `cat PATH/Description.txt`
update table_ticket set description = :'content' where ticketnr = TICKETNR;

投入我创建了以下一个简单的脚本如下:

#!/bin/bash
for i in `find . -type d|grep ^./CS`
do
    p=`echo $i|cut -b3-12 -`
    echo $p
    sed s/PATH/${p}/g cmd.sql > cmd.tmp.sql
    ticketnr=`echo $p|cut -b5-10 -`
    sed -i s/TICKETNR/${ticketnr}/g cmd.tmp.sql
    cat cmd.tmp.sql
    psql -U supportAdmin -h localhost supportdb -f cmd.tmp.sql
done

缺点是,它总是会创建一个新的连接,以后我会改变以创建单个文件

但它不正是我一直在寻找,把一列里面的内容。



Answer 2:

psql ,除非你打算把它存储为一个大型对象在这种情况下,你可以使用不能直接读取该文件为你lo_import 。 请参阅psql命令\lo_import


更新 :@AlexandreAlves指出,你可以实际使用啜文件内容

  \set myvar = `cat somefile`

然后引用它作为一个psql具有可变:'myvar' 。 便利。


虽然它可以读取文件中使用shell和饲料它psql这将是笨拙充其量作为外壳提供既不与参数化查询的支持,也没有逃避功能的任何文本的本地PostgreSQL数据库驱动程序。 你必须推出自己的字符串逃脱。

即使是这样,你需要知道的是,输入文件的文本编码有效期为您client_encoding否则你会插入垃圾和/或出现错误。 它迅速登陆了是容易做它用像Python,Perl和Ruby或Java的PostgreSQL的正确整合langage。

一种方法做你想要在bash如果你真的必须,但:使用PG的分隔美元报价与随机分隔符,以帮助防止SQL注入攻击。 这不是完美的,但它是相当的接近。 现在我正在写一个例子。


鉴于问题的文件:

$ cat > difficult.txt <__END__
Shell metacharacters like: $!(){}*?"'
SQL-significant characters like "'()
__END__

和样表:

psql -c 'CREATE TABLE testfile(filecontent text not null);'

您可以:

#!/bin/bash
filetoread=$1
sep=$(printf '%04x%04x\n' $RANDOM $RANDOM)
psql <<__END__
INSERT INTO testfile(filecontent) VALUES (
\$x${sep}\$$(cat ${filetoread})\$x${sep}\$
);
__END__

这可能是一个有点难以阅读和随机串生成是bash的具体,但我敢肯定,有可能会移植的方法。

包括字母数字字符(I为方便起见使用十六进制)的随机代码字符串生成并存储在seq

psql然后与未引述这里文档标签调用。 缺少引用的是很重要的,因为<<'__END__'会告诉bash不是字符串,wheras平原内解释shell元字符<<__END__允许外壳对其进行解释。 我们需要shell来解释元字符,因为我们需要替换sep到这里的文件,也需要使用$(...)相当于反引号)插入文件的文本。 在x的每个取代之前seq有因为这里的文档标签必须是有效的PostgreSQL标识符所以他们必须以字母而不是数字开头。 有开始和每个标签的结束是一个转义美元符号,因为PostgreSQL的美元报价的形式为$taghere$quoted text$taghere$

因此,当脚本调用为bash testscript.sh difficult.txt here文档的土地高达扩大到类似:

INSERT INTO testfile(filecontent) VALUES (
$x0a305c82$Shell metacharacters like: $!(){}*?"'
SQL-significant characters like "'()$x0a305c82$
);

其中标签每一次变化,使得SQL注入的攻击依赖于过早地结束报价困难。

我还是建议你使用一个真正的脚本语言,但是这表明,它确实是可能的。



Answer 3:

做的最好的事情是创建一个临时表,COPY那些问题的文件,然后运行您的更新。

你的第二选择是创建像PL / perlu语言的函数,在存储过程中做到这一点,但你会失去很多性能优化,当你从一个临时表更新,你可以做。



文章来源: updating table rows based on txt file