This issue cropped up because runrig posted a "DBI bind_param_inout trick" node (http://perlmonks.org/?node_id=989136) on perl monks which when I ran through DBD::ODBC did not work. The code is basically:
my $dbh = DBI->connect; my @cols = qw(foo bar); my $sql = <<SQL; SELECT :foo, :bar SQL my $sth = $dbh->prepare($sql); my %hsh; for (@cols) { $sth->bind_param_inout( "$_" => \$hsh{$_}, 0 ); } # Set constants... $hsh{foo} = 'abc'; # Set changing values $hsh{bar} = 123; $sth->execute(); while (my @arr = $sth->fetchrow_array) { print "@arr\n"; } $hsh{bar} = 456; $sth->execute(); while (my @arr = $sth->fetchrow_array) { print "@arr\n"; } $dbh->disconnect(); which should output: abc 123 abc 456 but actually outputs: Use of uninitialized value $arr[0] in join or string at /tmp/x.pl line 33. 123 Use of uninitialized value $arr[0] in join or string at /tmp/x.pl line 39. 456 The problem is that DBD::ODBC binds the parameter initially when bind_param_inout is called then when execute is called it needs to determine if the parameters need to be rebound (if something significant has changed). It uses the following test: if (SvTYPE(phs->sv) != phs->sv_type /* has the type changed? */ || (SvOK(phs->sv) && !SvPOK(phs->sv)) /* is there still a string? */ || (SvPVX(phs->sv) != phs->sv_buf) /* has the string buffer moved? */ ) { /* rebind the parameter */ } I have some issues with this (in addition to it not working): 1. DBD::ODBC always calls SvUPGRADE(phs->sv, SVt_PVNV) on output parameters so the type is unlikely to change. 2. DBD::ODBC always calls SvGROW on output parameters to grow them to 28 chrs (some magic about 28 I don't know) to avoid mutation in most cases. As a result, if you change the test code so the first param is bigger than 28 chrs it works. 3. I don't understand what the (SvOK(phs->sv) && !SvPOK(phs->sv)) is for. I know what those macros do but not why that test is present. Any ideas? It is in other DBDs too. 4. I'm unsure how to make this work although if I simply add a test to say has SvOK(phs->sv) changed since binding it makes this example work. Anyone any ideas if this is sufficient? Thanks. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com