Dúvida sobre a melhor lógica

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
xprata
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 93
Registrado em: Ter, 06 Abr 2010 11:31 am
Localização: São Paulo - SP

Boa tarde pessoal.
Tenho o seguinte cenário.
Controlar um estacionamento onde tenho clientes (ex. dentistas, lojas, consultórios), que possuem uma cota de estacionamento por dia.
Ex. o dentista X pode estacionar 10 carros diariamente as 2,00 reais a hora...se passar de 10 o valor vai para 7 reais a hora para o carro excedido (simplificando a regra), minimo de 1 hora.

Preciso criar uma consulta onde demonstre quanto tempo cada carro ficou excedido no dia.
Tenho uma tabela com a informação de placa, dt entrada, dtsaida e cliente (entre outras colunas).

Fiz um programa com a seguinte lógica: tentei um portugol +-

"
Seleciono os registros para o período informado

Selecionar tudo

SELECT data_saida,data_entrada,placa,id_cliente
from tb_Estacionamento
WHERE 
data_entrada BETWEEN to_timestamp('01/01/2014 00:00:00','DD/MM/YYYY HH24:MI:SS') 
AND                  to_timestamp('31/01/2014','DD/MM/YYYY HH24:MI:SS') and " +
ORDER BY a.data_entrada
Faço um LOOP lendo cada registro

Selecionar tudo

LOOP
  Para cada registro faço uma verificação obtendo no momento da entrada quantos carros tenho estacionado para o cliente e descobrindo se está excedendo 

  select count(*) as qtde,a.id_cliente
  from tb_Estacionamento
  WHERE placa <> "placa da linha em questão
  AND (to_timestamp('" + data de entrada da linha em questão + "','DD/MM/YYYY HH24:MI:SS') 
  between data_entrada and data_saida) " +
  and id_cliente = "Cliente da linha em questão"

Se a qtde > 10 -- carro excedido
   Incluo o registro em uma tabela temporario
   INSERT INTO tbAux VALUES (placa,id_cliente,data_entrada,data_saida)

EndLoop
Apos isso, pego os registros da tabela temporária e verifico quanto tempo ficou excedido cada registro.

Selecionar tudo

SELECT * FROM tbAux ORDER BY data_entrada
Faço um LOOP lendo cada registro

Selecionar tudo

LOOP
    Crio uma variável para pegar a data inicial de cada registro, que será igual a data de entrada
    _variavelDataI = "data de entrada da linha em questão"
    faço um LOOP ate encontrar a data em que o veiculo saiu de excedente, isso é feito a partir da data de entrada e vou somando uma hora, pois o minimo é uma hora
    LOOP
        select count(*) as qtde,id_cliente
        from tb_Estacionamento
        WHERE placa <> "placa da linha em questão
        and id_cliente = "Cliente da linha em questão"
        AND data_entrada <= to_timestamp('" + _variavelDataI + "','DD/MM/YYYY HH24:MI:SS') " +
        AND data_saida >= to_timestamp('" + _variavelDataI + "','DD/MM/YYYY HH24:MI:SS') " +
        group BY id_cliente;

        se qtde < 10 ou data_saida da linha em questão <= a variável  - _variavelDataI
          atualizo  a tabela auxiliar informado a data  que saiu -  _variavelDataI
          update tbAux set data_saida_excedente = to_timestamp('" + _variavelDataI + "','DD/MM/YYYY HH24:MI:SS')
          where placa = placa da linha em questão
          e saio do loop

        se não
          eu incremento a variável  _variavelDataI em uma hora e volto ao começo DO loop                                         
    endloop 

endLoop 

Espero ter deixado claro...

Vamos definitivamente as dúvidas:
1 - O que acham da lógica? Será que esta certo ?
2 - Coloquei isso dentro do código de programação, adianta colocar em StoredProcedure ?
3 - Como melhorar a performance ?
4 - Existe outra forma melhor?

Obrigado
t+
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Boa tarde xprata,

Existem várias formas de fazer a mesma coisa (isto é lógica), maneira de se chegar a um mesmo lugar mas de modo diferente,isto depende de cada um. O que vai determinar se é a melhor ou não, é se atende as necessidades do cliente e agrega valor ao negócio do mesmo. Ainda assim, a lógica está intrisecamente relacionada as regras de negócio, que vai determinar aquilo que você pode ou não fazer. Na minha opinião, o que vai determinar a performance da consulta é como esta base de dados foi modelada (DER - Diagrama Entidade Relacionamento) e a volumetria, dentre outros fatores.

Apenas para eu tentar entender. Nesta mesma tabela "tb_Estacionamento" você tem registros relacionados à cliente, controle de fluxo de veiculos (datas, horarios), valores?

Sinceramente não tive muito tempo para analisar o seu codigo (estou no trabalho neste momento, mas assim que possível dou uma olhada), mas ajudaria se você disponibilizasse as tabelas envolvidas e as colunas principais evidenciando os dados que gostaria de retornar/visualizar.

Att.,
Responder
  • Informação