DBD::OCBC support for XML datatype in SQL Server 2005

[email protected] (Michael Ludwig)
Newsgroups perl.dbi.users
Message-ID <20100915001853.GA5944@wladimir>
I'm facing encoding issues in trying to make use of the XML datatype in
SQL Server 2005, which I'm accessing using DBD::ODBC 1.23 and Perl 5.12.

  CREATE TABLE T2 (a VARCHAR(99), u NVARCHAR(99), x XML);

Three columns here, a for single-byte characters, u for Unicode, and
x for XML.

The following statements works correctly in SSMS (SS Management Studio):

  INSERT INTO T2 VALUES ('Käse', N'Käse', CAST( '<d>Käse</d>' AS XML));

  Käse    Käse    <d>Käse</d>

Now German wasn't too difficult, so let's try some Russian.

  INSERT INTO T2 VALUES
  ('Москва', N'Москва', CAST('<r>Москва</r>' AS XML));
  INSERT INTO T2 VALUES
  ('Москва', N'Москва', CAST(N'<r>Москва</r>' AS XML));

  ??????  Москва  <r>??????</r>
  ??????  Москва  <r>Москва</r>

We need the N introducer for Unicode literals and a column type capable
of receiving Unicode data. Failing any of those two, we're getting just
a series of substitution characters (?).

How can we handle this situation from Perl? Here's a script.

          \,,,/
          (o o)
------oOOo-(_)-oOOo------
use strict;
use warnings; no warnings 'uninitialized';
use utf8;
use DBI;

my $txt_de = 'Käse';
my $txt_ru = 'Москва';

binmode STDOUT, ':utf8';

my @dsn = qw/DBI:ODBC:MY_DB my_username my_password/;
my %opt = (PrintError => 0, RaiseError => 1, AutoCommit => 1);
my $dbh = DBI->connect( @dsn, \%opt );
$dbh->{LongReadLen} = 4000;
$dbh->{LongTruncOk} = 1; # Dies muß, ob logisch oder nicht.

my $sth_ins = $dbh->prepare(
  'INSERT INTO T2 (a, u, x) VALUES (?, ?, CAST( ? AS XML) )' );
$sth_ins->execute( $txt_de, $txt_de, "<d>$txt_de</d>" );
$sth_ins->execute( $txt_ru, $txt_ru, "<r>$txt_ru</r>" );

my $sth_sel = $dbh->prepare( 'SELECT u, x FROM T2' );
$sth_sel->execute;
$sth_sel->bind_columns( \my( $txt, $xml ) );
my $i = 0;
while ( $sth_sel->fetch ) {
  printf "%3u %3u [%s] [%s]\n", ++$i, length($txt), $txt, $xml;
}
$dbh->disconnect;
-------------------------

The problem is the INSERT statement, more specifically, in the XML part.
I can't seem to get it to accept my Unicode strings as Unicode for that
column. Instead, they're treated as octets, resulting in garbage.

  Käse   Käse    <d>Käse</d>
  Москва Москва  <r>Москва</r>

I've tried to use an N introducer with the XML column, but that leads to
errors.

  CAST( N? AS XML)      - Invalid column name 'N@P3'. (SQL-42S22)
  CAST( N ? AS XML)     - Incorrect syntax near '@P3'. (SQL-42000)

I'd appreciate your advice.
-- 
Michael Ludwig
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.