My hope was, that DBI::sql_type_cast with the DBIstcf_DISCARD_STRING-flag would modify $sv from ‘4.8g’ to 4.8.
(DBIstcf_DISCARD_STRING:
“If this flag is specified then when the driver successfully casts the bound perl scalar to a non-string type then the string portion of the scalar will be discarded.”)
What does the return-value sv could not be case and DBIstcf_STRICT was not used mean?
#!/usr/bin/env perl
use warnings;
use 5.012;
use DBI qw(:sql_types);
my $dsn = "DBI:Proxy:hostname=horst;port=2000;dsn=DBI:ODBC:db1.mdb";
my $dbh = DBI->connect( $dsn, undef, undef, { RaiseError => 1, PrintError => 0 } )
or die $DBI::errstr;
my $sv = '4.8g';
my $sql_type = SQL_DOUBLE;
my $flags = DBIstcf_DISCARD_STRING;
my $sts = DBI::sql_type_cast( $sv, $sql_type, $flags );
say $sts; # 1 (sv could not be case and DBIstcf_STRICT was not used)
say $sv;
# Argument "4.8b" isn't numeric in subroutine entry at ./perl6.pl line 14.
# 1
# 4.8b
The documentation contains a typo — the description for
$sts== 1 should be “sv could not be cast” — i.e. a cast toSQL_DOUBLEwasn’t possible for the value you provided and so nothing was done.DBIstcf_DISCARD_STRINGmeans something different from what you want. In Perl internal terms it means that if you pass an SV withPOKandNOKand PV part"1.23"and NV part1.23, you will get back an SV with!POKandNOKand NV part1.23— that is, the stored string part of the scalar will be invalidated, leaving the numeric part intact, so any future attempt to use the scalar as a string will force it to be re-converted from a number to a string. But note that it says that this will only happen if the cast is successful, and a cast toSQL_DOUBLEisn’t successful if the value isn’t a valid number to begin with. “4.8g” doesn’t pass the test.You can clean up the string part of the value almost as effectively as DBI on your own just by doing
$sv = 0 + $sv;which will clearPOKand force a reconversion to string in the same way. The difference between this and what DBI does is that it’s not actually clearing the PV in the way that DBI would, only marking it invalid. To force the value to be cleared immediately in the same way as DBI, you need to do something like$sv = do { my $tmp = 0 + $sv; undef $sv; $tmp };but unless you have some really good explanation for why you need that, you don’t — so don’t use it. 🙂