【发布时间】:2015-10-28 18:16:46
【问题描述】:
首先我将描述我所拥有的,然后是问题。
我有一个这样结构的文本文件
----------- Start of file-----
<!-->
name,name2,ignore,name4,jojobjim,name3,name6,name9,pop
-->
<csv counter="1">
1,2,3,1,6,8,2,8,2,
2,6,5,1,5,8,7,7,9,
1,4,3,1,2,8,9,3,4,
4,1,6,1,5,6,5,2,9
</csv>
-------- END OF FILE-----------
我还有一个带有映射的 perl 程序:
my %column_mapping = (
"name" => 'name',
"name1" => 'name_1',
"name2" => 'name_2',
"name3" => 'name_3',
"name4" => 'name_4',
"name5" => 'name_5',
"name6" => 'name_6',
"name7" => 'name_7',
"name9" => 'name_9',
)
我的动态插入语句(假设我正确连接到数据库,并且标题是我的标题名称数组,例如 test1、test2 等)
my $sql = sprintf 'INSERT INTO tablename ( %s ) VALUES ( %s )',
join( ',', map { $column_mapping{$_} } @headers ),
join( ',', ('?') x scalar @headers );
my $sth = $dbh->prepare($sql);
现在我实际遇到的问题是: 我需要一种方法来只对标题和地图中的值进行插入。 在作为示例给出的数据文件中,有几个名称不在地图中,有没有办法可以忽略它们以及在 csv 部分中与它们关联的数字?
基本上是做一个子集csv,把它变成:
name,name2,name4,name3,name6,name9,
1,2,1,8,2,8,
2,6,1,8,7,7,
1,4,1,8,9,3,
4,1,1,6,5,2,
这样我的插入语句只会在地图中插入那些。数据文件总是不同的,而且顺序也不一样,地图中会出现未知的数量。
这是执行此操作的理想方法,因为此脚本将遍历数千个文件,并且每个文件都位于 csv 的数百万行和数百列之后。
它只是一个正在读取的文本文件,而不是 csv,不确定 csv 库是否可以在这种情况下工作。
【问题讨论】:
-
@ThisSuitIsBlack 不太确定这只是用于标题,但是否确定要在 csv 部分跳过哪些数据?我不相信它确实如此
-
啊,我明白你在问什么。你是对的,它没有。
-
@ThisSuitIsBlackNot 在他更新后我意识到这不会解决它。我认为这是我将遇到的最后一个与 perl 相关的问题。这个脚本对我来说相当复杂,因为我昨天还不知道 perl,哈哈。所以不幸的是,在一些地方被难住了......
-
你问了一个新问题是对的,我很抱歉没有仔细阅读。这是一个相当复杂的任务,在 Perl 学习了一天之后就必须完成!
-
您在使用未转义的
@headers时有潜在的SQL 注入攻击。它们至少应该通过DBI->quote_identifier运行。最好使用SQL::Abstract 来构造您的SQL 语句或ORM 或类似DBIx::Class。
标签: perl csv dictionary subset sql-insert