[APRENDIZ]Analisando bloco PL/Sql

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
paulaholti
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Sex, 29 Jan 2010 4:02 pm
Localização: sp
iniciante oracle pl/sql forms reports

Oi, eu fiz esse bloco pl/sql, está testado e funciona direitinho. Gostaria apenas de saber se a estrutura dos comandos estão dispostas de forma apropriadas. Queria apenas saber tem muita coisa para deixar o codigo mais "refinado" . Por exemplo não sei se está certo eu fazer essas tres selects assim uma atrás da outra.. Como posso melhorar ?

obrigada!

Selecionar tudo

Accept p_idlocacao prompt ' Entre com o id da locacao : ' ;
Accept p_idfita prompt ' Entre com o ID da fita : ' ;


Declare

v_idlocacao locacao.id_locacao%type := &p_idlocacao ;
v_idfita fitas.id_fitas%type := &p_idfita;

v_verloca number(1);
v_fita_alugada number(1);
v_verfita number(2);


begin

  select count(*) into v_verloca from locacao where id_locacao = v_idlocacao;

  select count(*) into v_verfita  from fitas where id_fitas = v_idfita ;

  select count(*) into v_fita_alugada
  from locacao a, itens_locacao b, fitas c
  where a.id_locacao = b.id_locacao and
        b.id_fitas = c.id_fitas and
        b.id_fitas = v_idfita and
       a.dataentrega is null ;
 

if v_verloca = 0 then 
   
   dbms_output.put_line (' Esse id de locacao não existe');

elsif v_verfita = 0 then 

   dbms_output.put_line (' Esta fita não existe');

elsif v_fita_alugada >= 10 then

    dbms_output.put_line (' Esta fita não tem em estoque');

else

insert into itens_locacao values (v_idlocacao,v_idfita);


end if;

commit work ;

end ;

/
paulaholti
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Sex, 29 Jan 2010 4:02 pm
Localização: sp
iniciante oracle pl/sql forms reports

Hum usar a palavra 'refinado' num codigo desse bem pequeno e simples, foi muita pretensao ..

Na minha primeira tentativa eu tava usando IF dentro de Elses, dá no mesmo ou um jeito é menos eficiente que outros ? Poderia até usar CASES, mas não vi necessidade ..

não achei propicio, chamar funcoes para algo que resolvo numa select.

obrigada!
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5018
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Eu gostei... Já que é algo simples, ta bom! está facil de entender.
Eu só colocaria mais comentários, e indentação melhor.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Se você utiliza o PL/SQL Developer tem um recurso chamado
PL/SQL Beautifier, você faz o seu estilo para cada comando, salva esse estilo e depois pode aplica-lo nas folhas do SQL Window, onde tem seus códigos.

=]
paulaholti
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Sex, 29 Jan 2010 4:02 pm
Localização: sp
iniciante oracle pl/sql forms reports

Obrigada 'pelas' dicas. :P

Tava pensando,
logo de cara ele execute tres selects de uma so vez, para só depois verificar as existências de dados. Caso as duas primeiras selects não obedecem as regras de existência, então a terceira select é executada desnecessariamente. Isso não iria ser ruim para o banco, caso fosse algo com milhoes de linhas ? ..

Vou ver se contorno isso, para fazer somente o terceiro select caso os dois primeiros sejam satisfatório .

o b r i g a d a ! !

* a identencao faço como ? . Tabulacao, ou espaços com barra de espaço?. Existe um padrão ?
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

Com toda certeza que se não é necessário melhor não executar,

mesmo que fosse uma linha, sei lá, pra que ??

a identação, eu utilizado 2 espaços,

em qualquer ferramente você pode configurar quantos espaçoes o TAB vai "pular",

o ideal é usar o TAB,

mas no fim o que importa é o visual, tornando o código mais legivel,

=)
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Isso não iria ser ruim para o banco, caso fosse algo com milhoes de linhas ?
Mais que isso, na verdade é um problema se essa procedure for executada milhares ou milhões de vezes.

Nesse caso você teria que atentar para problemas de concorrência, pois entre o seu count(*) e seu insert pode ser que outro usuário tenha executado a mesma procedure ao mesmo tempo e feito o insert antes de você. Nesse caso sua base acabou de ficar inconsistente e vai ser preciso a famosa "marreta" para consertar, e pode haver prejuízo e uma situação delicada para o cliente ou para o negócio.

O jeito de prevenir isso ou é mudando o isolation level da transação ou dando um lock nas tabelas e linhas usadas (select for update ou lock explícito).
paulaholti
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Sex, 29 Jan 2010 4:02 pm
Localização: sp
iniciante oracle pl/sql forms reports

Selecionar tudo

O jeito de prevenir isso ou é mudando o isolation level da transação ou dando um lock nas tabelas e linhas usadas (select for update ou lock explícito). 
O banco não faz isso sozinho ? ... Como seria isto ?.

* mas no caso, se fosse no forms, dispararia uma trigger para ver se a condicao do campo satisfaz para continuar em outro campo, ai nessa caso (não satisfaz) não iria fazer selects "atoa". Mesmo assim tem que se preocupar os Locks ?

------------------------------------------------------------------------

Usar o Count(*) é melhor do que usar a coluna que ser quer achar ?

------------------------------------------------------------------------

não consegui, fazer com que não faça os selects sem precisar, não existe um EXIT (ou qualquer outra coisa) dentro do IF para abortar ?

O b r i g a d a a t o d o s ! ! !
:)
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

O banco não tem como garantir que entre o seu select count(*) e seu insert os dados não foram deletados ou modificados, pois você precisa explicitamente solicitar um lock nas linhas ou na tabela como um todo.

A chance é pequena mas cresce na proporção que mais e mais usuários utilizam seu sistema concomitantemente.

A forma de implementar vai depender do que torna a transação atômica na lógica de negócio, incluindo o que vem antes desse script acima. Por exemplo, a inserção na tabela "locacao" se ocorrer sozinha sem inserir também em "itens_locacao" constitui um problema? Esse tipo de questionamento vai definir que operações constituem sua transação.

Recomendo ler os conceitos sobre o assunto para entender a importância disso tudo:
http://download.oracle.com/docs/cd/E118 ... onsist.htm

Depois siga para o "como fazer":
- Como fazer locks manualmente para controlar a consitência da transação:
http://download.oracle.com/docs/cd/E118 ... cks003.htm

-Comando para alterar nível de isolamento de transação:
http://download.oracle.com/docs/cd/E118 ... _10005.htm
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Não leve muito ao pé da letra as coisas que digo também. Não é nenhum bicho de sete cabeças, principalmente se o seu sistema não possuir vários usuários acessando ao mesmo tempo, e por aí vai. São conceitos importantes mas sua utilização vai depender de sistema para sistema. Eventualmente você vai precisar, talvez não hoje mas é sempre bom saber as alternativas para quando for desenvolver algo com requisitos novos.

Abraço,
Francisco.
paulaholti
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Sex, 29 Jan 2010 4:02 pm
Localização: sp
iniciante oracle pl/sql forms reports

Entendi mais ou menos, esses locks ..
Só uma duvida, um Select * from locacao for update <= trava a tabela inteira para tudo ? ... Onde que destrava, que não achei nenhum comando ( lock table off ??????) .

Mas, sem querer correr do problema, acho que o DBA avisaria da necessidade ou não de um lock*, ou viajei ?

O b r i g a d a ! ! ! ! !

* claro, que temos a responsabilidade de saber controlar essas travas.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

destrava quando sua transacao terminar, rollback / commit
Responder
  • Informação