【问题标题】:Character set problems with Perl, DBD::Oracle and Oracle 10gPerl、DBD::Oracle 和 Oracle 10g 的字符集问题
【发布时间】:2011-04-06 14:09:24
【问题描述】:

在我们的 Oracle 10g 数据库中,基本 ASCII 集以外的字符显示为倒置的问号时存在问题。

我有以下脚本来加载一些测试数据。该脚本在 Komodo IDE 的远程 UNIX 服务器上保存为 Latin-1/ISO-8859-1:

#!/wload/espd/app/perl/bin/perl

use strict; 
use warnings;
use Encode;
use esp_libs_db;
my $dbh = espDbConnectNew();

my $sql = q{ INSERT INTO DBUSER.test VALUES ('qwérty')};

#$sql = encode("iso-8859-1", $sql);

my $rows = $dbh->do($sql)  or Carp::croak "ERROR: PM_DB_0010:[" . $DBI::errstr . "]   Cannot run stmt:\n";;
print $rows;
$dbh->commit();
$dbh->disconnect();



sub espDbConnectNew {
    my ( $database ) = @_;    
    my %connectionStrings = &esp_libs_db::espGetConnectionStrings( $database );

    # Set Environment Variables
    $ENV{ORACLE_SID}=$connectionStrings{"SID"};
    $ENV{ORACLE_HOME}=$connectionStrings{"HOME"};
    my $dbh = DBI->connect("dbi:Oracle:SID=$connectionStrings{'SID'};HOST=$connectionStrings{'HOST'};PORT=$connectionStrings{'PID'}",
    "$connectionStrings{'USER'}","$connectionStrings{'PWD'}",
    {PrintError=>0,
    RaiseError => 0,
    AutoCommit => 0}
) or Carp::croak "ERROR: PM_DB_0003:  Cant connect to db:\n";


    return $dbh;
} #espDbConnect

它加载到的数据库是 Oracle 10g 数据库,具有以下参数:

NLS_NCHAR_CHARACTERSET  AL16UTF16
NLS_LANGUAGE    ENGLISH
NLS_TERRITORY   UNITED KINGDOM
NLS_CHARACTERSET    WE8ISO8859P1

测试表上的单列是 VARCHAR2(255) 类型。

尽管花了一整天的时间阅读这些问题,但我真的不知道如何解决/诊断确切的问题。

我已经尝试过在执行之前使用和不使用 Encode 对 SQL 字符串进行编码。

谢谢

【问题讨论】:

    标签: perl oracle character-encoding dbi dbd


    【解决方案1】:

    当您得到颠倒的问号时,您是如何检索数据的?您要检索数据的客户端上的 NLS_LANG 环境变量是什么?

    在 SQL*Plus 中,你能运行吗

    SELECT dump( column_name, 1013 ), column_name
      FROM DBUSER.test
    

    然后发布结果? DUMP 函数显示数据库中实际存储的内容——这将显示问题出在存储重音字符上还是问题出在检索重音字符上。

    【讨论】:

    • 我在 PLSQL 中,我不确定如何判断它使用的是什么 NLS_LANG。 AMERICAN_AMERICA.WE8MSWIN1252 是注册表中的内容,但我不知道是否有任何东西可以覆盖它。如果我运行转储,那么我会得到Typ=1 Len=6 CharacterSet=WE8ISO8859P1: 113,119,191,114,116,121 qw¿rty。如果我选择 UNIX 服务器上的数据,我会看到同样的问题。这只是一个小测试脚本,用于删除内容类型字符集等因素。
    • 澄清我在使用 DBI 时没有在 UNIX 客户端上明确设置 NLS_LANG。
    • 我不确定“在 PL/SQL 中”是什么意思。你的意思是 SQL*Plus 吗?根据 DUMP 的输出,问题似乎在于存储字符(ISO 8859-1 中的 191 是倒置问号字符)。能否在运行脚本之前将 UNIX 客户端上的 NLS_LANG 设置为 AMERICAN_AMERICA.WE8ISO8859P1?
    • 对不起 - 错过了一个相当关键的词......我的意思是全方位自动化的“PLSQL Developer”。在设置 ORACLE_HOME 之后,我尝试添加行 $ENV{NLS_LANG} = 'AMERICAN_AMERICA.WE8ISO8859P1';。然后在尝试连接到数据库时出现错误。不幸的是,$DBI::errstr 只是说它在检索错误文本时遇到了问题。我是否设置了 NLS_LANG 错误?
    • 我已经在我们的新系统上测试了同样的东西,该系统具有更新版本的 DBI、DBD 和 oracle 客户端,并且设置 NLS_LANG 可以正常工作并允许我正确存储字符。现在我只需要看看升级我们当前的系统。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-08-23
    • 2016-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2012-04-04
    相关资源
    最近更新 更多