FAQ
I seem to have identified the difference between selecting from nchar and
nvarchar columns containing unicode data:

for nvarchar:
col 1: dbtype 1, scale 0, prec 512, nullok 1, name A
: dbsize 512, char_used 1, char_size 256, csid 2000, csform 2, disize 512

for ncahr:
col 1: dbtype 96, scale 0, prec 512, nullok 1, name A
: dbsize 512, char_used 1, char_size 256, csid 2000, csform 2, disize 512

and for nvarchar, DBD::Oracle makes the call:

calling OCIAttrSet OCI_ATTR_CHARSET_FORM with csform=2
OCIAttrSet(83423a0,OCI_HTYPE_DEFINE,bfffed87,0,32,833c858)=SUCCESS

If I change oci8.c around line 1316 which was:

#ifdef OCI_ATTR_CHARSET_FORM
if ( (fbh->dbtype == 1) ) { /* && (fbh->csform == SQLCS_NCHAR) &&
CS_IS_UTF8(ncharsetid) ) { */
/* ok... after doing what tim asked: setting SvUTF8 strictly based on csid
8bit Nchar test was broken
and this currently effectively just sets Attrs to the values in fhb ignoring
ncharsetid altogether
probably wrong
*/

to:

#ifdef OCI_ATTR_CHARSET_FORM
if ( (fbh->dbtype == 1) || (fbh->csform == SQLCS_NCHAR)) {

I seem to get my data back as I expected.

I don't know much about DBD::Oracle so the comment in the code does
not help me that much but it looks as though the code used to be
fairly similar to how I changed it.

So, my question now becomes, should I be able to store unicode data
in an nchar (which I can with stock DBD::Oracle 1.16) and expect to be
able to get it back again as unicode data? Is DBD::Oracle working
correctly or should I have done something else?

Martin

--
Martin J. Evans
Easysoft Ltd, UK
Development
On 19-Jul-2005 Martin J. Evans wrote:
Hi,

I have some further information on my problem. The insertion of UTF-8 data
into
nchar seems to work like it does for nvarchar2; it appears it is the
selecting
from nchar fields that is not returning the data inserted. I have verified
this
by inserting the same data into nchar and nvarchar fields and reading it via
Oracle's ODBC driver in MS Access - where it looks fine. But, retrieving it
in
Perl does not display the same results.

Martin
--
Martin J. Evans
Easysoft Ltd, UK
Development

On 18-Jul-2005 Martin J. Evans wrote:
Hi,

Wondered if anyone can tell me if I've misunderstood something here. I am
able
to insert unicode data into nvarchar2 and get back what was inserted but
same
code with nchar column does not work.

OCI version is 10.1.0.2
Database is Oracle 10.2 on Linux
Database CHAR set is WE8ISO8859P1 (Non-Unicode), NCHAR set is AL16UTF16
(Unicode)
This is perl, v5.8.7 built for i686-linux
DBD::Oracle 1.16.

#!/disk2/martin/perl/bin/perl
use charnames ':full';
use DBI;
use Encode;
use DBD::Oracle qw( :ora_types ORA_OCI SQLCS_NCHAR );
use Devel::Peek;

if ( $] < 5.008) {
print "Need at least Perl 5.8\n";
exit 1;
}
binmode(STDOUT, ":utf8");

print "<html><head>";
print q|<meta http-equiv="Content-Type" content="text/html;charset=utf-8">|;
print "<title>test</title></head><body>\n";

$ENV{'ORACLE_HOME'} = '/home/oracle/product/10.1.0/db_2';
$ENV{'NLS_NCHAR'} = 'AL32UTF8';
my $dbh = DBI->connect('dbi:Oracle:tentwo.testing', 'xxx', 'yyy');
$dbh->{ChopBlanks} = 1;
print "OCI version is ", ORA_OCI, "\n";
print "ora_can_unicode = ", $dbh->ora_can_unicode, "\n";
if (!($dbh->ora_can_unicode & 1)) {
print "Database does not support UNICODE\n";
exit 1;
}
my $paramsH = $dbh->ora_nls_parameters();
printf "Database $ora_server_version CHAR set is %s (%s), NCHAR set is %s
(%s)\n",
$paramsH->{NLS_CHARACTERSET},
$dbh->ora_can_unicode & 2 ? "Unicode" : "Non-Unicode",
$paramsH->{NLS_NCHAR_CHARACTERSET},
$dbh->ora_can_unicode & 1 ? "Unicode" : "Non-Unicode";
eval {
$dbh->do('drop table martin');
};
# NOTE nchar does not work!!!! (why?)
$dbh->do('create table martin (a nvarchar2(256))');
my $sql = "insert into martin values (?)";
my $x = "\N{EURO SIGN}\x{20ac}\N{LATIN CAPITAL LETTER A WITH ACUTE}";
$x .= chr(0x20ac);
print "is_utf8 returns ", utf8::is_utf8($x), "\n";
print "valid returns ", utf8::valid($x), "\n";
my $sth = $dbh->prepare($sql);
$sth->bind_param(1, $x, {ora_csform => SQLCS_NCHAR});
$sth->execute();
$sql = "select a from martin";
$sth = $dbh->prepare($sql);
$sth->execute;
while(my @row = $sth->fetchrow_array) {
print "valid on returned string returns ", utf8::valid($row[0]), "\n";
#$_ = decode("utf8", $_) foreach @row;
print $row[0], "\n";
print unpack("H*", $row[0]), "\n";
print Dump(@row[0]);
}
$sth->finish;
$dbh->disconnect();

Output is:

<html><head><meta http-equiv="Content-Type"
content="text/html;charset=utf-8"><title>test</title></head><body>
OCI version is 10.1.0.2
ora_can_unicode = 1
Database CHAR set is WE8ISO8859P1 (Non-Unicode), NCHAR set is AL16UTF16
(Unicode)
is_utf8 returns 1
valid returns 1
valid on returned string returns 1
<utf8 data here - snipped from email>
e282ace282acc381e282ac
SV = PV(0x82a3efc) at 0x82e5b48
REFCNT = 1
FLAGS = (POK,pPOK,UTF8)
PV = 0x8361bb0 "\342\202\254\342\202\254\303\201\342\202\254"\0 [UTF8
"\x{20ac}\x{20ac}\x{c1}\x{20ac}"]
CUR = 11
LEN = 12
</body></html>

UTF-8 data output with Devel::Peek Dump looks fine.

A simple change to create the table with nchar instead of nvarchar2
outputs:

<html><head><meta http-equiv="Content-Type"
content="text/html;charset=utf-8"><title>test</title></head><body>
OCI version is 10.1.0.2
ora_can_unicode = 1
Database CHAR set is WE8ISO8859P1 (Non-Unicode), NCHAR set is AL16UTF16
(Unicode)
is_utf8 returns 1
valid returns 1
valid on returned string returns 1
<utf8 data here snipped from email>
3f3f413f
SV = PV(0x82a3efc) at 0x82e5c3c
REFCNT = 1
FLAGS = (POK,pPOK,UTF8)
PV = 0x8361cc0 "??A?"\0 [UTF8 "??A?"]
CUR = 4
LEN = 5
</body></html>

Devel::Peek Dump output looks nothing like what I expected.

Also, do I have to use {ora_csform => SQLCS_NCHAR}? Does not seem to work in
either case if I don't.

And one final thing. If I change $x containing the UTF-8 data to insert and
run
$sth->execute again it inserts the original data again and not the changed
$x.
I've not confirmed this yet with other drivers, but I am /fairly/ sure with
DBD::ODBC you don't have to call bind_param again if the bound data is
changed.

Thanks.

Martin
--
Martin J. Evans
Easysoft Ltd, UK
Development

Search Discussions

Discussion Posts

Previous

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 4 of 4 | next ›
Discussion Overview
groupdbi-users @
categoriesperl
postedJul 18, '05 at 5:05p
activeJul 19, '05 at 1:32p
posts4
users1
websitedbi.perl.org

1 user in discussion

Martin J. Evans: 4 posts

People

Translate

site design / logo © 2023 Grokbase