Stringer has asked for the wisdom of the Perl Monks concerning the following question:

I've run across a strange bit of behavior within DBI. When I set the 'LongTruncOk' parameter to true for a database handle and retrieve a long string it seems to insert null bytes between each character. For example, a string of '600' comes back as (in hex):

36 00 30 00 30

This pattern persists throughout the string. This does not occur if LongTruncOk is set to false.

Is this expected behavior that I'm simply ignorant of? I want it to automatically truncate strings that are too long, but not if my string gets trashed in the process.

The following code reproduces the problem. I'm working with an MS SQL Server if it matters.

#!/usr/bin/perl use strict; use warnings; use DBI qw(:utils); my $data; my $host = 'somehost'; my $query = <<'END'; select someColumn from someDb.someSchema.someTable where id = someValue END $data = queryDb( 'host' => $host, 'query' => $query, 'longTruncOk' => 1, ); print $data->[0][0], "\n"; #Output as ASCII $data->[0][0] =~ s/(.)/sprintf("%x ",ord($1))/eg; print $data->[0][0], "\n"; #Output as hex sub queryDb { my %args = @_; my $connStr = 'DBI:ODBC:' . $args{host}; my $dbh = DBI->connect($connStr) or die "Couldn't connect to database: " . DBI->errstr . "\n"; my $table = []; $dbh->{LongReadLen} = defined $args{longReadLen} ? $args{longReadLen +} : 80; $dbh->{LongTruncOk} = defined $args{longTruncOk} ? $args{longTruncOk +} : 0; #Note - this seems to change strings to UTF-16? my $sth = $dbh->prepare($args{query}) or die "Couldn't prepare statement: " . $dbh->errstr . "\n"; $sth->execute( @{ $args{params} } ); while (my @row = $sth->fetchrow_array()) { push @$table, \@row; } return $table; }

Replies are listed 'Best First'.
Re: DBI Adding Null Bytes to String
by afoken (Chancellor) on May 25, 2016 at 22:16 UTC
    When I set the 'LongTruncOk' parameter to true for a database handle and retrieve a long string it seems to insert null bytes between each character. For example, a string of '600' comes back as (in hex): 36 00 30 00 30

    Looks like UTF-16.

    I'm working with an MS SQL Server if it matters.

    Yes, it does. Please show us the definition of the table you are reading from. Are you reading from an NVARCHAR (as opposed to a VARCHAR)?

    Could you try running the tests 40UnicodeRoundTrip.t, 41Unicode.t, and perhaps also 45_unicode_varchar.t from DBD::ODBC? (You will also need UChelp.pm from the same directory.)

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: DBI Adding Null Bytes to String
by GrandFather (Saint) on May 25, 2016 at 21:32 UTC

    Can you create a small test script that creates a database, adds a string to it and retrieves the string showing the issue?

    It is unlikely that LongTruncOk is the root of the problem. LongTruncOk is a DBI attribute that allows otherwise failing transfers to succeed by truncating them.

    Premature optimization is the root of all job security