使用perl DBI到数据库时中文乱码

时间:2021-04-22 11:23:41
本来我想用perl对xml文件进行分析,取出里边指定的value值,打一个csv文件出来,但是遇到中文乱码问题,经过和别人的交流已经解决此问题;后来我希望通过DBI直接将分析出的数据insert进数据库,中文乱码的问题又出现了。。请教各位如何解决,主要代码如下,有什么可以优化的地方请指教


#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;
use DBI;
use Encode;
use strict;
use encoding "gbk";

#判断是否传递XML文件参数
if (open(MYFILE, "$ARGV[0]")) {
    # here's what to do if the file opened successfully
    print "\n\"$ARGV[0]\" : file exist! parse beginning!\n";
    #获得EMS名称
    my @ems = split(/\_/,$ARGV[0]);
    print "@ems[1]\n";
    
    #获得XML文件数据
    my $data = XMLin($ARGV[0]);
#print Dumper($data);

#打印文件时间戳
print "Timestamp = $data->{'timestamp'}\n\n";

my $i = 0;
#判断是否存在下一条网元记录
print "appending to csv...\n";
while( $data->{'output'}->{'TopoMgr.NEAdditionalInfoType-array'}->{'TopoMgr.NEAdditionalInfoType'}->[$i] )
{
print "\@ record num = $i\n";

    my $text = "$data->{'output'}->{'TopoMgr.NEAdditionalInfoType-array'}->{'TopoMgr.NEAdditionalInfoType'}->[$i]->{'neName'}\n";

    print $text;
    
    #将分析出的数据追加到FILE末尾
    open(APPENDFILE, ">>perlne.dat");

    #转为utf-8后不报字符串过长异常,不转不影响效果
    Encode::_utf8_off($text); 
    print APPENDFILE ($text);
    close(APPENDFILE);
    
    # Connect to target DB
#my $dbh=DBI->connect("DBI:mysql:test:192.168.1.14", 'root', 'root');
my $dbh = DBI->connect( 'DBI:Oracle:ora10g','res_col','res_col');

#$dbh->do("SET character_set_client = 'utf-8'");
#$dbh->do("SET character_set_connection = 'utf-8'");
#$dbh->do("SET character_set_results= 'utf-8'");
#$dbh->do("SET names  'gbk'");
#Encode::_utf8_off($nename); 

# Insert one row 
my $rows = $dbh->do("INSERT INTO neinfo(text) VALUES ('$text')");

$dbh->disconnect();
    
    $i ++;
}

close(MYFILE);
# query 
my $dbh = DBI->connect( 'DBI:Oracle:ora10g','res_col','res_col');
my $sqr = $dbh->prepare("SELECT * FROM neinfo");
$sqr->execute();

while ( my @row=$sqr->fetchrow_array() )
{
        #print join('\t', @row)."\n";
        print join(',', @row)."\n";
}

$sqr->finish();
$dbh->disconnect();

print 'END...';

}unless (open (MYFILE, "$ARGV[0]")) {
    die ("cannot open input file $ARGV[0]\n");
    close(MYFILE);
}



<?xml version="1.0" encoding="GBK"?>
<outputlist timestamp="20090917232423">
<output>
<TopoMgr.NEAdditionalInfoType-array>
  <TopoMgr.NEAdditionalInfoType>
    <neId>134217729</neId>
    <neName>测试1 [1-1]</neName>
  </TopoMgr.NEAdditionalInfoType>
  <TopoMgr.NEAdditionalInfoType>
    <neId>134217731</neId>
    <neName>测试2 [1-2]</neName>
  </TopoMgr.NEAdditionalInfoType>
</TopoMgr.NEAdditionalInfoType-array>
</output>
</outputlist>


写入oracle后变成了这个样子,oracle设置的字符集为zhs16gbk
134217732    绾㈠湡宀� [1-3]
134217879    鐗х墰1 [1-4]

如果前边不加use encoding "gbk"; 会出现
使用perl DBI到数据库时中文乱码

如果不加Encode::_utf8_off($text); 会出现
使用perl DBI到数据库时中文乱码

正常情况下是不会出现下边的告警的

生成的csv文件一切正常,就是写入数据库后有问题,oracle和mysql都是一样的问题

16 个解决方案

#1


。。。图挂了~?
第一个是  中文各种乱码

第二个是  Wide character in print at plxml.pl line 73.   就是print APPENDFILE ($text);
 这句

#2


有没有高手帮我看看啊。。。。。愁死我了~

#3


打印出INSERT INTO neinfo(text) VALUES ('$text') 看看

#4


INSERT INTO neinfo(neid,nename) VALUES (134217734,'测试1 [1-1]')

正常

#5


oracle环境如下,我看有人说把字符集设置AMERICAN_AMERICA.US7ASCII,跟这个有关系吗

PARAMETER VALUE
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY ¥
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET ZHS16GBK
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY ¥
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE

#6


1 mysql client什么编码
2 mysql server什么编码
3 两者要一致。

#7


没那么复杂

#8


我。。。有点晕~~~~那看来就是数据库的事咯??perl脚本应该没什么问题是吧?

#9


character_set_client gbk
character_set_connection gbk
character_set_database gbk
character_set_filesystem binary
character_set_results
character_set_server gbk
character_set_system utf8


INSERT INTO neinfo(neid,nename) VALUES (134220760,'测试1')   --这句打出来的都没问题
DBD::mysql::db do failed: Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95...'
for column 'nename' at row 1 at plxml.pl line 94.     --这就报错了

#10


要看的是:
Server characterset:
Db     characterset:
Client characterset:
Conn.  characterset:

#11


还有perl的版本

#12


ActivePerl 5.10.1

#13


window下,不知道你是怎么连mysql的。我也对window下不熟。
用odbc ?还是其他方式。odbc的话,你的DSN设置编码的地方我估计要检查一下。

#14


刁董啊,跑着来发帖问路了?

#15


在插入数据库之前,你得保证你要插入的字符串的编码和数据库的编码保持一致。

#16


各种没看懂。。。。。。有没有解决办法啊???

#1


。。。图挂了~?
第一个是  中文各种乱码

第二个是  Wide character in print at plxml.pl line 73.   就是print APPENDFILE ($text);
 这句

#2


有没有高手帮我看看啊。。。。。愁死我了~

#3


打印出INSERT INTO neinfo(text) VALUES ('$text') 看看

#4


INSERT INTO neinfo(neid,nename) VALUES (134217734,'测试1 [1-1]')

正常

#5


oracle环境如下,我看有人说把字符集设置AMERICAN_AMERICA.US7ASCII,跟这个有关系吗

PARAMETER VALUE
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY ¥
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET ZHS16GBK
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY ¥
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE

#6


1 mysql client什么编码
2 mysql server什么编码
3 两者要一致。

#7


没那么复杂

#8


我。。。有点晕~~~~那看来就是数据库的事咯??perl脚本应该没什么问题是吧?

#9


character_set_client gbk
character_set_connection gbk
character_set_database gbk
character_set_filesystem binary
character_set_results
character_set_server gbk
character_set_system utf8


INSERT INTO neinfo(neid,nename) VALUES (134220760,'测试1')   --这句打出来的都没问题
DBD::mysql::db do failed: Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95...'
for column 'nename' at row 1 at plxml.pl line 94.     --这就报错了

#10


要看的是:
Server characterset:
Db     characterset:
Client characterset:
Conn.  characterset:

#11


还有perl的版本

#12


ActivePerl 5.10.1

#13


window下,不知道你是怎么连mysql的。我也对window下不熟。
用odbc ?还是其他方式。odbc的话,你的DSN设置编码的地方我估计要检查一下。

#14


刁董啊,跑着来发帖问路了?

#15


在插入数据库之前,你得保证你要插入的字符串的编码和数据库的编码保持一致。

#16


各种没看懂。。。。。。有没有解决办法啊???