Re: [Cascavel-pm] Duvidas em passar o valor 0 (zero) para uma função.

Luis Campos de Carvalho monsieur_champs em yahoo.com.br
Quarta Março 9 17:51:20 PST 2005


Rod Za wrote:
> Eu não sei, sempre me confundo como o Perl interpreta o valor 0 (zero)! Me parece q na funcão q eu
> descrevi o valor passado, quando zero, é sempre interpretado como se fosse FALSE (ou mesmo NULL) e
> não como o número 0 (zero)!.

   É simples de entender: depois de qualquer interpolação, a string '0' 
se torna indistinguível de undef(), automagicamente. Isto é um erro 
comum mesmo entre os experts... ;-)

   Se você precisa mesmo interpolar uma string contendo o valor zero, o 
melhor meio de fazer é escrever um zero que, ao ser interpretado, se 
torne "verdadeiro". Assim, por exemplo: "0E0". Ou "0, but true". Ambos 
serão automagicamente tratados como zero em contextos numéricos, mas 
serão "verdadeiro" em contextos de string.

   Claro, isso não pode ser usado na interpolação de comandos SQL por 
razões muito mais que óbvias... ;-P

> Luiz quando ao uso de PlaceHolders, a minha verdadeira funcão não é tão simples quanto a q eu
> apresentei anteriormente, só fiz deste modo para melhor ilustrar o tipo de erro q vem acontecendo.
> A verdadeira funcão faz parte de uma classe e é a seguinte:
> 
> <code>
> sub user_update($%){
>         my $self = shift;
>         my %update = @_;
>         my @keyArray = keys %update;
>         my @valueArray;
>         my $return;
>         foreach(@keyArray){
>                 push @valueArray, $self->{dbh}->quote($update{$_}) if defined($update{$_});
>         }
>         my $sql = "INSERT INTO history (`".join('`,`', em keyArray)."`) VALUES
> (".join(',', em valueArray).")";
>         $self->commit if($self->{dbh}->do($sql));
> }
> <code>

   Bom, isso é simples de reescrever. :-)

   Você está fazendo a segunda coisa mais comum quando se programa DBs 
com perl: está construindo queries dinamicamente, com quantidade 
variável de parâmetros.

   Para resolver o problema, deve construir o query com a quantidade 
correta de placeholders, ao invés de passar os valores para serem 
interpolados diretamente no SQL. Depois, pode passar o array de valores 
a serem inseridos/modificados para o método DBD::execute() apropriado. 
Assim:

__PERL__
sub user_update($%){
   my $self = shift;
   my %update = @_;
   my @keyArray = keys %update;
   my @valueArray;
   my $return;
   #
   # Não precisa mais usar DBI::quote() contra os valores.
   # O mecanismo de placeholders se encarrega disso.
   #
   my $sql =  'INSERT INTO history ( '. join(', ', @keyArray )
             .' ) VALUES ( ' . join( ',', '?'x em valueArray ) .')';
   my $sth = $self->{dbh}->prepare( $sql );
   my $result = $sth->execute( @valueArray );
   $self->commit if $result;
}
__END__

   Carinha, eu *não* *testei* este código, em absoluto.
   *Certamente* existem pequenas correções que você precisa fazer para 
que ele execute corretamente (sintaxe, talvez alguma lógica).

   Ah! Uma última coisa: você paga a cerveja no próximo encontro 
nacional, tá? ;-)

   Putamplexos, e bom divertimento!
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  Luis Campos de Carvalho is BSc in Comp Science,
  PerlMonk [SiteDocClan], Sao Paulo PM Leader,
  Unix Sys Admin && Certified Oracle DBA
  http://br.geocities.com/monsieur_champs/
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=



Mais detalhes sobre a lista de discussão Cascavel-pm