我使用文本::CSV读取CSV文件,解析字段,然后通过DBI将记录写入SQL Server。除了我必须操纵的日期字段之外,所有字段都是金色的。
CSV中日期字段的格式为,例如,“2013年12月20日星期五14:56:54”。当然,SQLServer不喜欢这种格式。呃,在脚本中,我使用了这个块:
if ( $i == 12 || $i == 13 || $i == 22 || $i == 23 || $i == 24 || $i == 25)
{
if ( defined $fields[$i] )
{
$dummy = UnixDate($fields[$i],'%m/%d/%Y %H:%M:%S');
$fields[$i] = $dummy;
}
}
(定义的检查是因为如果CSV中的字段包含单词“None”,那么我正在对该元素进行undef,以便该字段在插入到DB中时为NULL。在此示例行中,除元素24和25之外的所有列/字段均为“None(无)”。)
打开DBI跟踪显示:
<- bind_param(19, '1')= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(20, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(21, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(22, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(23, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(24, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(25, "12/20/2013 14:56:54")= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(26, "12/20/2013 14:55:37")= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(27, 'Unknown')= ( 1 ) [1 items] at upload_merged_host.pl line 71
因此,您可以看到CSV中的其他字段/列已正确绑定(上面的“1”和“未知”),但我操作的日期字段/列现在有双引号,SQL对此并不满意。
为了更清楚,如果我不操作日期字段,它正确地包含单引号,但不再是SQLServer可接受的格式:
<- bind_param(19, '1')= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(20, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(21, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(22, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(23, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(24, undef)= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(25, 'Fri Dec 20 14:56:54 2013')= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(26, 'Fri Dec 20 14:55:37 2013')= ( 1 ) [1 items] at upload_merged_host.pl line 71
<- bind_param(27, 'Unknown')= ( 1 ) [1 items] at upload_merged_host.pl line 71
希望有任何建议!
使现代化
:@Vinbot的评论让我尝试了一些东西。与其使用UnixDate操纵日期字符串,不如在一开始就将一周中的某一天砍下来。现在看起来是这样的:
$fields[$i]=子字符串($fields$$i],4);
我在痕迹中看到的
应该
现在开始吧:
...
<- bind_param(25, 'Dec 20 15:33:42 2013')= ( 1 ) [1 items] at upload_merged_host.pl line 93
...
但我仍然得到了铸造错误,和以前一样。直接对sql使用相同的格式没有问题(例如,通过sqlservermanagementstudio):
INSERT INTO <schema>.dbo.host(hostname,interface_ipaddress,interface_name,host_modified_date) VALUES ('some_host','10.1.1.1','Local Area Connection','Dec 20 15:33:42 2013')
工作正常。
更新2
我能够使用不同的日期操作例程,现在问题已经解决了(尽管我仍然需要优化更改,但至少是功能性的)。
解决方案是使用DateTime和DateTime::Format::DBI。到目前为止,我必须手动操作从CSV传入的日期字符串,以将其传递给DateTime->new(),然后将该值传递到DateTime::Format::DBI->format_datetime()。
希望在一段时间的睡眠后,我可以消除我刚才所做的一些暴力!:)