[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