Проблемы с набором символов в Perl, DBD::Oracle и Oracle 10g

#perl #oracle #character-encoding #dbi #dbd

#perl #Oracle #кодировка символов #dbi #dbd

Вопрос:

У нас проблема с символами за пределами базового набора ASCII, которые отображаются в виде перевернутых вопросительных знаков в нашей базе данных Oracle 10g.

У меня есть следующий скрипт для загрузки некоторых тестовых данных. Скрипт сохранен как Latin-1 /ISO-8859-1 на удаленном UNIX-сервере из Komodo IDE:

 #!/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 = amp;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 перед ее выполнением.

Спасибо

Ответ №1:

Как вы извлекаете данные, когда получаете перевернутые вопросительные знаки? Что такое переменная среды NLS_LANG на клиенте, откуда вы извлекаете данные?

В SQL * Plus можете ли вы запустить

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

и опубликовать результаты? Функция ДАМПА показывает, что на самом деле хранится в базе данных — это покажет, заключается ли проблема в сохранении символа с ударением или проблема в извлечении символа с ударением.

Комментарии:

1. Я работаю в PLSQL и не уверен, как определить, какой NLS_LANG он использует. AMERICAN_AMERICA.WE8MSWIN1252 — это то, что есть в реестре, но я не знаю, может ли что-нибудь переопределить это. Если я запускаю дамп, то получаю Typ=1 Len=6 CharacterSet=WE8ISO8859P1: 113,119,191,114,116,121 qw¿rty . Я вижу ту же проблему, если я выбираю данные на сервере UNIX. Это всего лишь небольшой тестовый скрипт для устранения таких факторов, как кодировки типов контента.

2. Чтобы уточнить, я не устанавливаю NLS_LANG явно на UNIX-клиенте при использовании DBI.

3. Я не уверен, что означает «в PL / SQL». Вы имеете в виду SQL * Plus? Судя по выводам дампа, проблема заключается в сохранении символа (191 в ISO 8859-1 — перевернутый символ вопросительного знака). Можете ли вы установить для NLS_LANG на клиенте UNIX значение AMERICAN_AMERICA. WE8ISO8859P1 перед запуском скрипта?

4. Извините — пропустил там довольно важное слово… Я имел в виду «разработчика PLSQL» под всесторонней автоматизацией. Я попытался добавить строку $ENV{NLS_LANG} = 'AMERICAN_AMERICA.WE8ISO8859P1'; после того, как задано значение ORACLE_HOME. Затем я получаю сообщение об ошибке при попытке подключиться к базе данных. К сожалению, в $ DBI::errstr просто говорится, что возникла проблема с извлечением текста ошибки. Я неправильно настраиваю NLS_LANG?

5. Я протестировал то же самое в нашей новой системе, которая имеет гораздо более новые версии DBI, DBD и клиента oracle, и настройка NLS_LANG работает и позволяет мне правильно сохранять символы. Теперь мне просто нужно посмотреть на обновление нашей текущей системы. Спасибо.