[SP-pm] a minha duvida passo a passo

Luis Motta Campos luismottacampos at yahoo.co.uk
Mon Nov 3 10:54:40 PST 2008


Danilo de souza lima wrote:
> Esse é um baita select onde para cada consulta feita armazeno numa variavel perl
[código monstruoso, horrível, mal-escrito e mal-formatado aqui]

OK, levou 40 minutos para eu conseguir desembaraçar esta coisa, mas eu 
finalmente terminei. Agora vamos às minhas conclusões:

1. Tua base de dados é um lixo, eu demitiria o teu DBA com justa causa;
2. O teu modelo entidade-relacionamento é um mapinha do inferno, uma
    vergonha para a sociedade. Como eu sei isso? Basta olhar para os
    nomes das tuas colunas para ver que você não tem um mínimo de
    normalização na tua base de dados.
3. É fácil ver que só sendo pai-de-santo para fechar a contabilidade
    na escola onde você trabalha. Eu recomendo fortemente que você
    comece a sugerir um trabalho de reengenharia para fatorar a tabela
    FINAN_ENTRADA em pelo menos 4 tabelas diferentes. Eu estou à
    disposição para ajudar a desmembrar esta zorra, se você quiser.
4. Teu query recebe um parâmetro, mas você não deve colocar ele como uma
    variável interpolada. Ao invés disso, eu implementei a tua query como
    uma constante, e usei um /placeholder/ (o caracter "?", no query)
    para implementar a passagem de parâmetro. Leia sobre isso na
    documentação do DBI.
5. Você também precisa repensar a forma como você trata erros de accesso
    à base de dados: teu código é inconsistente, usando "die" e
    verificando valores de retorno dos comandos DBI de uma forma
    aleatória. Escolha um dos dois métodos e fique com ele. Você
    provavelmetne precisa refatorar seu código para corrigir isso também.
6. Você realiza montes de cálculos inúteis e coloca montes de valores
    que eu duvido que você realmente chegue a usar no seu SQL para
    retornar ao cliente. Eu optaria por uma solução com menos trabalho
    para a base de dados. Por exemplo, todas as datas calculadas tem o
    nome do dia da semana junto, e isso você pode calcular mais tarde, na
    aplicação, ou com um javascript bem pequeno, no lado do cliente. Isso
    ajudaria muito a evitar queries inúteis e certamente melhoraria o
    desempenho da sua base de dados. Também ajudaria a reduzir a
    quantidade ridícula de informação que você carrega para lá e para cá
    no seu programa, efetivamente evitando de usar muita memória RAM que
    você poderia aproveitar para outras coisas.
7. Se você prestar atenção no seu SQL, vai ver que eu nomeei as colunas.
    Isso permite que: A) o teu DBA de merda consiga debugar o SQL dele,
    separadamente, sem precisar quebrar a cabeça por horas para saber que
    campo é o quê; e B) que o DBI nomeie as colunas e retorne os valores
    corretos nos lugares que você espera no hash dos resultados. Use
    sempre esta técnica, ou você vai terminar com números que parecem
    datas nas suas colunas de pagamento, e nunca mais vai conseguir
    fechar o balanço desta baiúca.
8. Finalmente, mas não menos importante: pelamordosdeuses separa o
    código perl do SQL do HTML, sim? Isso facilita a você entender o
    Perl, e também ao pessoal que mantém o SQL e o HTML a compreender o
    que eles estão fazendo de uma forma melhor. Vai ajudar muito mesmo
    que você seja o único coitado que mexe com todos os três componentes.

A minha versão do seu código, mais limpa, fácil de entender e simples de 
manter:

__PERL__
use DBI;
use constant LONG_DUMP_STUPID_QUERY = <<SQL ;
SELECT DATE_FORMAT( CURDATE(), '%d/%m/%Y' ) AS "data_atual"
      , UPPER( LEFT( DAYNAME( CURDATE() ), 3 ) ) AS "data_atual_nome"
      , FE.id AS "id"
      , FE.FINAN_SERVICO_id AS "serv_id"
      , UPPER( FS.codigo ) AS "serv_codigo"
      , UPPER( FS.descr ) AS "serv_descr"
      , UPPER( FS.CENTRO_DE_CUSTOS_codigo ) AS "centro_custos_codigo"
      , (
          SELECT UPPER( CC.descr )
          FROM CENTRO_DE_CUSTOS AS CC
          WHERE CC.codigo = FS.CENTRO_DE_CUSTOS_codigo
          LIMIT 1
        ) AS "centro_custos_descr"
      , FE.EVENTO_PROC_SELETIVOS_INSCR_id AS "evento_inscr_id"
      , (
          SELECT UPPER( I.nome )
          FROM EVENTO_PROC_SELETIVOS_INSCR AS I
          WHERE I.id = FE.EVENTO_PROC_SELETIVOS_INSCR_id
          LIMIT 1
        ) AS "evento_inscr_nome"
      , RMC.nome AS "matr_nome"
      , FE.CURSOS_id AS "curso_id"
      , (
          SELECT UPPER( CC.sigla )
          FROM CURSOS AS CC
          WHERE CC.id = FE.CURSOS_id
          LIMIT 1
        ) AS "curso_sigla"
      , FE.ano AS "ano"
      , FE.semestre AS "semestre"
      , FE.mes AS "mes"
      , UPPER( FE.descr ) AS "descr"
      , FE.total_parcelas AS "total_parcelas"
      , FE.parcela_atual AS "parcela_atual"
      , FE.valor_total AS "valor_total"
      , FE.valor_com_deconto AS "valor_com_desconto"
      , FE.valor_pago AS "valor_pago"
      , FE.dias_tolerancia AS "dias_tolerancia"
      , FE.juros_mora_percent AS "juros_mora_percent"
      , FE.juros_pro_rata_percent AS "juro_pro_rata_percent"
      , FE.juros_mora_pago_valor AS "juros_mora_pago_valor"
      , FE.juros_pro_rata_pago_valor AS "juros_pro_rata_pago_valor"
      , DATE_FORMAT( FE.pgto_data_previsto, '%d/%m/%Y' )
          AS "pgto_data_prev"
      , UPPER( LEFT( DAYNAME( FE.pgto_data_previsto ), 3 ) )
          AS "pgto_data_prev_nome"
      , DATE_FORMAT( FE.pgto_data_efetivado, '%d/%m/%Y' )
          AS "pgto_data_efet"
      , UPPER( LEFT( DAYNAME( FE.pgto_data_efetivado ), 3 ) )
          AS "pgto_data_efet_nome"
      , DATEDIFF( CURDATE(), FE.pgto_data_previsto )
          AS "pgto_dias_em_atraso_prev"
      , DATEDIFF( FE.pgto_data_efetivado, FE.pgto_data_previsto )
          AS "pgto_dias_em_atraso_efet"
      , FE.pgto_dinh_valor AS "pgto_dinh_valor"
      , FE.pgto_boleto_valor AS "pgto_bol_valor"
      , FE.pgto_cheque_valor AS "pgto_chq_valor"
      , FE.total_de_cheques AS "pgto_chq_valor_total"
      , FE.pgto_deposito_valor AS "pgto_dep_valor"
      , FE.total_de_depositos AS "pgto_dep_total"
      , FE.pgto_negociacao_valor AS "pgto_neg_valor"
      , FE.total_de_negociacao AS "pgto_neg_total"
      , FE.negociacao_justif AS "pgto_neg_just"
      , FE.promissoria AS "prom"
      , UPPER( FE.obs ) AS "obs"
      , DATE_FORMAT( FE.data_reg, '%d/%m/%Y' ) AS "data_reg"
      , LEFT( DAYNAME( FE.data_reg ), 3 ) AS "data_reg_nome"
      , UPPER( FE.resp_nome ) AS "resp_nome"
      , FE.cancelado_data AS "canc_data"
      , LEFT( DAYNAME( FE.cancelado_data ), 3 ) AS "canc_data_nome"
      , FE.cancelado_justif AS "canc_just"
FROM FINAN_SERVICO AS FS
    , FINAN_ENTRADA AS FE
    , REQ_MATR_CTRL AS RMC
WHERE RMC.id = FE.REQ_MATR_CTRL_id
   AND FE.id = ?
SQL

sub my_database_sucks_and_i_cant_code {
     my ( $dbh, $alvo ) = @_;
     return -1 unless $dbh;
     return -2 unless $alvo;

     my $row = eval {
       $dbh->selectrow_hashref( LONG_DUMP_STUPID_QUERY,
                                undef, $alvo )
     };
     die $dbh->errstr if $@;
     return $row;
}
__END__

> tenho q efetuar a seguinte operacao ARQ_VALOR_DEVIDO =
> ($ARQ_PGTO_DINH_VALOR+$ARQ_PGTO_BOL_VALOR) - $ARQ_VALOR_TOTAL

Posso saber o que isso tem a ver com o monstrinho que você enviou acima? 
Você está esperando que alguém aqui implemente isso para você?

> preciso fazer com q esse valor calculado va para o html por meio de
> javascript,ou sera qnao precisa de javascritp

Ou eu estou ficando gagá com a idade, ou algum detalhe me escapa. Eu 
simplesmente não consigo entender o que é que Javascript tem a ver com 
um trecho de código que faz query para uma base de dados. Será que você 
pode me explicar?

Como você pode ver, a forma como você organiza o código te faz perder o 
foco e pensar na coisa errada. Você precisa urgentemente de 
reorganização e refatoração do seu código, para fazer com que tudo 
fucnione bem.

Espero que isso ajude você a entender quão ruim é a tua aplicação agora, 
e quanto você precisa melhorar. Lembre-se: um sistema financeiro que a 
gente não entende é como jogar dinheiro pelo ralo, a gente não sabe onde 
vai a grana de qualquer forma - mas o ralo certamente dá menos trabalho 
para manter funcionando. ;)

Putamplexos.
-- 
Luis Motta Campos is a software engineer,
Perl Programmer, foodie and photographer.


More information about the SaoPaulo-pm mailing list