> Date: Wed, 30 Jun 2010 10:24:24 +0100
> From: martin.ev...@easysoft.com
> To: lvir...@gmail.com
> CC: dbi-users@perl.org
> Subject: Re: What is the technique to supply a list of values to a where 
> clause?
> 
> Larry W. Virden wrote:
> > I am working on a quick tool to update some records in an oracle
> > database.
> > 
> > The code is similar to some other tools I've cobbled together, but in
> > this case, the where clause has a "column in list" clause. The
> > relevant pieces of code are:
> > 
> > my $aenlist = "(1127, 1557, 1661, 3030, 3982, 5205, 453, 8838,
> > 9338)";
> > my $tmpsuper1 = 406;
> > 
> > 
> > $updateSuper = $oraProdDBH->prepare
> > (
> > "UPDATE HR_INFO SET " .
> > "SUPERVISOR_EMP_NO=? , REC_MOD_DATE=SYSDATE " .
> > "WHERE " .
> > "ALT_EMP_NO IN ? AND SUPERVISOR_EMP_NO = 0"
> > ) or die "Failed to prepare - $DBI::errstr\n";
> > $urc = $updateSuper->execute($tmpsuper1, $aenlist) or die "Failed
> > to execute - $DBI::errstr\n";
> > 
> > When I try to run the code, DBI returns an error saying that the value
> > supplied by $aenlist isn't a number. And that's true - it is a string.
> > 
> > So, I tried setting $aenlist to (1127, 1557, 1661, 3030, 3982, 5205,
> > 453, 8838, 9338); and perl tells me there's a useless constant. That's
> > when I thought that what I really need to do was use @aenlist. Alas,
> > when I changed the execute to say
> > my @aenlist = (1127, 1557, 1661, 3030, 3982, 5205, 453, 8838, 9338);
> > :
> > :
> > my $urc = $updateSuper->execute($tmpsuper1, @aenlist) or die "Failed
> > to execute - $DBI::errstr\n"
> > 
> > ; now I get a DBD::Oracle::st execute failed error that I called
> > execute with 10 variables when 2 were needed.
> > 
> > So, I am hoping someone might be able to point me to some information
> > about how to encode the execute so that I pass a list to the where
> > clause.
> > 
> > Thank you so much for your help.
> > 
> > 
> 
> I'm presuming you have one SQL statement to do updates and a list of
> values for your where clause. You cannot do what you've tried above
> because DBI sees 2 parameters in your SQL not the 10 you've passed. You
> need to do:
> 
> 1. Change your SQL to construct a where clause using "in"
> 
> e.g.,
> $sql = q/update HR_INFO SET SUPERVISOR_EMP_NO=? , REC_MOD_DATE=SYSDATE
> WHERE SUPERVISOR_EMP_NO = 0 AND ALT_EMP_NO IN (/ . join(',', @aenlist) .
> ')';
> 
> Personally I don't like this and some database engines have a limit on
> how many items they can handle in the "in" clause.
> 
> 2.
> 
> prepare(q/update HR_INFO SET SUPERVISOR_EMP_NO=? , REC_MOD_DATE=SYSDATE
> WHERE ALT_EMP_NO IN ? AND SUPERVISOR_EMP_NO = 0/);
> 
> foreach (@aenlist) {
> execute($tmpsuper1, $_);
> }
> 
> 3. use execute_array - see the DBI docs. This would probably be my
> preferred method but it is a little more complicated to use than 2 above
> especially if you need to know exactly which updates had an effect.
> 

 

I would have to disagree with Martin on this it :).  The Execute_array is very 
easy to use

 

you have 

 

 my @aenlist = "(1127, 1557, 1661, 3030, 3982, 5205, 453, 8838, 9338)";

 my $tmpsuper1 = (406,406,406,406,406,406,406,406,406);

  

 

$sth = $dbh->prepare("UPDATE HR_INFO 

                                      SET SUPERVISOR_EMP_NO=?, 

                                             REC_MOD_DATE=SYSDATE " 

                                 WHERE ALT_EMP_NO = ? AND SUPERVISOR_EMP_NO = 
0");

 

$sth->
  my $tuples = $sth->execute_array(
      { ArrayTupleStatus => \my @tuple_status },
      \...@tmpsuper1 ,
      \...@aenlist ,
  );


which is not that hard and it is also standard DBI so it should work on every 
version of DBI/DBD.  As a bonus some DBD will use thier own processing for the 
command. For examples DBD::Oracle has a native array execute that will save you 
alot of processing cycles if you have large (1000+) updates to do.

 

 

 

Cheers

John Scoles

 

> Martin
> -- 
> Martin J. Evans
> Easysoft Limited
> http://www.easysoft.com

                                          
_________________________________________________________________
Look 'em in the eye: FREE Messenger video chat
http://go.microsoft.com/?linkid=9734386

Reply via email to