[Cascavel-pm] OFF - mudar script perl de MYSQl para Postgre

Luis Motta Campos luismottacampos em yahoo.co.uk
Sexta Julho 6 11:18:21 PDT 2007


Patty Silva wrote:
> Ola Pessoal.. coloquei como assunto OFF .

   Você não precisa avisar isso, Patty...
   A gente consegue ler. ;-)

> Estou com um problema.. no MYSQL tenho um campo na minha tabela que eh
> 
> inc TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE 
> CURRENT_TIMESTAMP,
> 
> como irei fazer isso no POSTGRE?

   Os tipos de dados do MySQL e do Postgres são quase completamente 
compatíveis. Os teus TIMESTAMPs, por exemplo, são compatíveis e podem 
ficar como estão. Consulte sobre os outros aqui:

   http://www.postgresql.org/docs/8.2/static/datatype.html


   Consulte a documentação do comando CREATE TABLE para entender e 
aplicar os detalhes:

   http://www.postgresql.org/docs/8.2/static/sql-createtable.html

> outra duvida:
> 
> no MYSQL:
> Insert into tabela1(ID,Data) values($id,$data) on duplicate key update 
> $update";
 >
 > e no POstGre?
 >

   Hum. Você tem péssimo SQL aqui. Vamos começar fácil:

   1. Não interpole variáveis no SQL. Você dá a impressão para a base de 
dados que todas as vezes tem um query diferente (os valores mudam), e a 
base não consegue usar o Library Cache para aproveitar os parse-trees do 
SQL (que é sempre o mesmo).
   2. SQL é uma linguagem de programação com convenções próprias. 
Respeite as convenções. Eu reproduzi o teu SQL com as convenções e 
identação respeitadas:

     INSERT INTO tabela1 ( ID, Data )
       VALUES ( ?, ? )
       ON DUPLICATE KEY
         UPDATE Data = ? -- eu estou presumindo isto, mas deve ser.

   Repare que eu respeitei a identação, escrevi os comandos de SQL em 
maiúsculas (como é tradicional) e inseri "placeholders" ("?") para 
informar ao MySQL que eu vou ter valores diferentes a cada query, mas 
sempre usando a mesma estrutura básica (isso aumenta a performance do banco)

   Agora, vamos à má notícia: O Pg não implementa diretrizes ON 
DUPLICATE KEY, elas não são padrão do SQL (isso quer dizer outro padrão 
não respeitado - vê como não respeitar padrões atrapalha?)

   Para obter o mesmo efeito, você precisa fazer tratamento de erros:

   sub insert_or_update_data {
     my ( $dbh, $id, $data ) = @_;

     # O certo era você manter o SQL num arquivo
     # separado, mas assim já  está aceitável
     my $query = <<'SQL';
INSERT INTO tabela1 ( ID, Data )
   VALUES ( ?, ? )
SQL

     # lembre-se de verificar sua conexão de base de dados.
     die q{No database connection} unless $dbh->ping;

     # Eu estou assumindo que você é esperta e usa
     # { RaiseError => 1, PrintError => 0, AutoCommit => 0 }
     # como tuas opções para abrir conexões com a base
     eval {
         $sth = $dbh->prepare( $query );
         $res = $sth->execute( $id, $data );
         $sth->dbi_commit;
     };
     if ( $@ ) {
         # temos erros, se for o nosso, tratamos.
         # Se não, lançamos uma excessão.
         # Pesquise qual é a resposta correta para
         # este erro, eu não me lembro de cabeça.
         if ( $@ =~ m{duplicate key} ){
           # Erro de chave duplicada!
           # chama a função de atualização e retorna
           return update_data( $dbh, $id, $data );
         }
         # Qualquer outro erro, die().
         die; # o die() reaproveita o conteúdo de $@.
     }
}

> se alguem puder me ajudar: D

   Eu sempre posso te ajudar, Patty.
   Agora vamos ver se você consegue se ajudar: espero que o código que 
você está gerando do outro lado seja pelo menos igual ao meu... e copiar 
não vale ;-) eu não testei o código, você está por sua conta!

   Putamplexos!
-- 
Luis Motta Campos (a.k.a. Monsieur Champs) is a software engineer,
Perl fanatic evangelist, and amateur {cook, photographer}


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