Laboratório de Banco de Dados II
Aula 1
Stored Procedures
Stored procedures
Uma seqüência de comandos SQL pode ser agrupada, formando uma stored procedure. A sua execução é
comandada, invocando-se o nome da stored procedure. No entanto, é mais do que simplesmente um substituto
ao agrupamento de comandos SQL.
1. Considerações sobre stored procedure
a) Se a seqüência de comandos é submetida várias vezes, não há a necessidade de submeter toda a
seqüência novamente, bastando invocar o nome da procedure. É mais econômico do ponto de vista de
codificação. Quando é preciso alterar alguma coisa, bastar alterar num único ponto da procedure; Não
repetir as correções em todos os pontos em que a seqüência se repete dentro de uma aplicação.
b) Os comandos são pré-compilados e armazenados no banco de dados em formato de execução pelo banco
de dados. Ou seja, não há a necessidade de re-compilação do código fonte sempre que a execução for
comandada. O gerenciador já fez uma análise do código fonte no momento da criação da procedure e
não precisa repeti-la em todas as execuções. A parte que precisa ser re-avaliada na execução é o plano
de acesso, pois este pode mudar de acordo com os dados.
c) Diminui a quantidade de mensagens trocadas entre o requisitante e o servidor, porque toda a seqüência é
executada no escopo do servidor. Do contrário, cada comando da seqüência é enviada ao servidor e
retornada ao requisitante antes do envio do próximo comando. Entre estes comandos podem ser
transferidos dados em volume significativo em termos de resultados intermediários ou mesmo finais a
serem aplicados definitivamente no banco de dados. Dependendo do número de comandos, isto impacta
no tempo de resposta.
d) Existe um ganho na segurança. Você não concede acesso às tabelas, mas concede somente o direito de
execução sobre as procedures, estabelecendo com mais rigor quais operações o usuário pode executar.
e) Os comandos de controle transacional podem ser deslocados para dentro do SGBD. Quando comandado
pela aplicação, eventos de comunicação podem produzir bloqueios demorados sobre os recursos, por
conexões aparentemente inativas.
f) Podem ser passados parâmetros de execução.
g) As aplicações tornam-se menos portáveis com a utilização de stored procedures.
2. Alguns comandos que podem fazer parte de uma procedure
Vamos considerar apenas casos simples, tendo em vista que os diversos gerenciadores apresentam códigos
proprietários e não temos interesse em cobrir muitos aspectos específicos.
As stored procedure são análogas às procedures em Pascal ou function em C. Admitem parâmetros de
entrada/saída. Permitem a utilização das construções SQL já estudadas, além de outras, como comandos de
controle do fluxo de execução e loop e declaração de variáveis.
Vamos, rapidamente, rever alguns comandos válidos no laboratório:
Declaração de variáveis
declare @var1
@var2
@var3
@var4
.
.
.
int,
char(10),
float,
varchar(32),
Controle de fluxo:
if (Boolean_condition)
begin
.
.
.
End
else
begin
.
.
.
End
Na parte de condição qualquer expressão booleana pode ser utilizada, inclusive aquelas presentes na cláusula
where, como exists, etc...
Repetição:
while (condition)
begin
.
.
.
end
Controle de fluxo numa estrutura de repetição:
1. break -- interrompe o fluxo de execução de um loop.
while (Boolean_condition)
begin
.
.
If (condition)
break
.
.
end
2. continue – reinicia o loop sem executar os comandos seguintes dentro do loop
while (Boolean_condition)
begin
.
.
If (condition)
continue
.
.
end
Abandonar a execução da stored procedure:
If (condition)
begin
...
Return
end
Atribuição de valores às variáveis:
set @var1 = 10,
@var2 = 'abcd adb',
@var3 = 123.87
Atribuição às variáveis de valores obtidos do banco de dados:
select @var1 = habitantes,
@var2 = nome,
@var3 = habitantes / 1000.0
from tb_cidades
where codigo = 'A99999'
Atribuição às variáveis de valores obtidos do banco de dados com a cláusula TOP:
declare @codigo char(15)
select top 1 @codigo = codigo
from tb_cidades
order by codigo -- nestes casos, importante a cláusula de ordernação
Concatenção de strings:
Utilizar o operador "||" (duplo símbolo pipe)
Exemplo:
select 'abc' || '123' from dual; -- Oracle
set @variavel = @variavel_1 || 'xyz'
select @variavel = nome || sobre_nome
from tb_cidades where codigo = 'A999999'
No Lab do nosso curso, você pode também, indistintamente, utilizar o símbolo "+"
select 'abc' + '123'
set @variavel = @variavel_1 + 'xyz'
select @variavel = nome + sobre_nome
from tb_cidades where codigo = 'A999999'
SQL opera conjuntos de registros/linhas
Não podemos presumir que os comandos afetam somente um registro.
Pode afetar um conjunto vazio, unitário ou com vários elementos.
Resultados podem não ser os esperados se você não levar em conta a multplicidade dos registros afetados.
Por exemplo,
declare @codigo char(20)
select @codigo = codigo from tb_cidades
Se existem várias linhas da tabela, qual o valor da variável?
Obtenção dos primeiros registros de uma consulta (Esclarecimento quanto à cláusula TOP)
Às vezes, estamos interessados somente nos primeiros registros de um conjunto que satisfazem às condições de
seleção. Para isto utilizamos a cláusula “top n”.
Exemplo:
select top 5 *
from tb_cidades
select
from
where
order
top 2 codigo, nome
tb_cidades
nome = 'Santos'
by nome
delete top 10 from tb_cidades
delete top 10 from tb_cidades where nome = 'São Pdro
update top 2 tb_cidades
set habitantes = 100
where nome = 'Santos'
Como atribuir valores às variáveis quanto se utiliza a cláusula TOP:
declare @codigo char(15)
select top 1 @codigo = codigo
from tb_cidades
order by codigo -- nestes casos, importante a cláusula de ordernação
a) A tabela é classificada em ordem crescente de código;
b) A primeira linha deste resultado é obtida;
c) O valor da coluna código desta linha obtida é atribuída à variável. Em outras palavras, é uma maneira
artificial de atribuir à variável o menor código presente na tabela.
Verificação da existência de registros selecionados ou afetados
Existem várias formas de verificação da existência de registros que satisfazem a certa condição, ou mesmo se
um comando SQL selecionou ou afetou registros. Em capítulos posteriores, veremos outras formas de
verificações.
No laboratório, o SGBD disponibiliza uma variável global que imediatamente após o comando pode ser
consultada para saber quantas linhas foram selecionadas, inseridas, alteradas ou removidas. A variável tem o
nome
@@rowcount
Por exemplo:
declare @codigo_cidade_corrente
select top 1 @codigo_cidade_corrente = codigo,
@qtd_habitantes_corrente = habitantes
from tb_cidades
where habitantes > @qtd_habitantes_corrente
order by habitantes
if (@@rowcount = 0)
begin
.
.
-- acabou...
.
.
end
.
.
.
Comando para criação de stored procedure
create procedure pr_exemplo (lista de parâmetros e respectivos tipos) as
begin ....... comandos sql .... end
Comando para remoção de stored procedure
drop procedure pr_lista_cidade
Comando para emitir uma mensagem
print "Esta é uma mensagem..."
Exemplo de criação de stored procedure
create procedure pr_lista_cidade (@cod_cid varchar(15))
as
begin
declare @nome_cid varchar(30)
select @nome_cid = nome
from tb_cidades
where codigo = @cod_cid
if (@@rowcount = 0)
begin
print "cidade não existe."
return
end
select @cod_cid, @nome_cid
select codigo,
nome,
habitantes
qtd_ruas,
estado
from tb_cidades
where codigo = @cod_cid
-- fim do código fonte
end
;
4. Observações sobre o exemplo
a) Neste exemplo específico, os resultados poderiam ser obtidos de forma mais simples. A codificação
exemplifica as formas de utilização de algumas estruturas.
b) A última linha contém somente um comentário “--”.
c) Execute um comando de cada vez. Neste caso, todo o texto refere-se a um único comando de criação de
procedure. Se você tentar executar mais que um comando, por exemplo, um drop procedure
pr_lista_cidade seguido do código fonte para a sua criação, ocorrerá erro. Será necessária a
colocação do terminador de comando que não é padrão. Se você utiliza a ferramenta do nosso ambiente,
como o msql, o terminador é “;”. Se estiver utilizando o browser, não poderá ser informado, porque o
envio indica o término da sequência de comandos. Ele depende da ferramenta cliente utilizada. Não faz
parte da procedure; Apenas informa que todo o fonte deve ser submetido ao servidor como um único
bloco de comandos.
d) Observe como a atribuição de variáveis é realizada. Esta sintaxe não é comum a todos os gerenciadores.
e) Para executar a procedure, substitua os valores dos parâmetros por algum que seja válido, nas chamadas
abaixo:
exec pr_lista_cidade 'aaa'
exec pr_lista_cidade 'bbb'
Atividade
Crie uma stored procedure de nome
pr_lista_dados_segunda_cidade
que faz o seguinte:
a)
b)
c)
d)
Recebe como parâmetro o código de uma cidade que consta da tabela tb_cidades;
Guarda em variável o número de habitantes da cidade correspondente ao código;
Se a cidade não existir, emite uma mensagem e termina a execução da procedure;
Utilizando, adequadamente, a estrutura “top n” e considerando que a cidade recebida como parâmetro
está em i-ésima posição em número de habitantes, mostra todos os dados de todas as cidades que estão
na posição i+2 em número de habitantes;
e) Seguindo raciocínio semelhante e supondo que a cidade recebida como parâmetro está em j-ésima
posição em quantidade de ruas, esta mesma procedure deve mostrar todos os dados de todas as cidades
que estão na posição j-2 em quantidade de ruas;
f) Observação: Na parte da apresentação, utilizar diretamente com “top n”, não produz o resultado
esperado porque não sabemos quantas cidades tem o mesmo número de habitantes e ruas e satisfazem à
condição de posição no “ranking”.
Por exemplo, suponha que existam as seguintes cidades apresentadas em duas ordenações diferentes.
a) Em ordem de habitantes:
codigo
--------------0002
0011
0013
0007
0008
0006
0009
0005
0004
0003
0012
0010
0001
nome
habitantes qtd_ruas
estado
------------------------------ ----------- ----------- -----BRASILIA
890
50000 DF
JK
10000
778 SP
SEGUNDA_MENOR
15000
6500 RJ
CEILANDIA
27000
6500 DF
BRASLANDIA
28000
8509 DF
SAO CARLOS
34235
501 SP
MAUA
35001
5301 SP
SAO CAETANO
47000
8600 SP
SANTO ANDRE
300001
50001 SP
TAGUATINGA
500001
32433 DF
SEGUNDA_MAIOR
500001
300 RJ
OSASCO
550001
80001 SP
SAO PAULO
9000000
500000 SP
b) Em ordem de quantidade de ruas
codigo
nome
habitantes qtd_ruas
estado
--------------- ------------------------------ ----------- ----------- -----0012
SEGUNDA_MAIOR
500001
300 RJ
0006
SAO CARLOS
34235
501 SP
0011
JK
10000
778 SP
0009
MAUA
35001
5301 SP
0007
CEILANDIA
27000
6500 DF
0013
SEGUNDA_MENOR
15000
6500 RJ
0008
BRASLANDIA
28000
8509 DF
0005
SAO CAETANO
47000
8600 SP
0003
TAGUATINGA
500001
32433 DF
0002
BRASILIA
890
50000 DF
0004
SANTO ANDRE
300001
50001 SP
0010
OSASCO
550001
80001 SP
0001
SAO PAULO
9000000
500000 SP
Executando
pr_lista_dados_segunda_cidade '0009' /* Mauá */
Os resultados são os seguintes:
codigo
--------------0003
0004
em habitantes */
0005
0006
em quantidade de
0007
0008
0009
0010
0001
0002
0011
0012
0013
nome
habitantes qtd_ruas
------------------------------ ----------- ----------TAGUATINGA
500001
32433
SANTO ANDRE
300001
50001
estado
-----DF
SP /* 2.a maior
SAO CAETANO
SAO CARLOS
ruas */
CEILANDIA
BRASLANDIA
MAUA
OSASCO
SAO PAULO
BRASILIA
JK
SEGUNDA_MAIOR
SEGUNDA_MENOR
DF
DF
SP
SP
SP
DF
SP
RJ
RJ
47000
34235
27000
28000
35001
550001
9000000
890
10000
500001
15000
8600 SP
501 SP /* 2.a menor
6500
8509
5301
80001
500000
50000
778
300
6500
Executando
pr_lista_dados_segunda_cidade '0005' /* São Caetano */
Os resultados são os seguintes:
codigo
nome
habitantes qtd_ruas
estado
--------------- ------------------------------ ----------- ----------- -----0003
TAGUATINGA
500001
32433 DF /* 2.a
em habitantes */
0004
SANTO ANDRE
300001
50001 SP
0005
SAO CAETANO
47000
8600 SP
0006
SAO CARLOS
34235
501 SP
0007
CEILANDIA
27000
6500 DF /* 2.a
em quantidade de ruas */
0008
BRASLANDIA
28000
8509 DF
0009
MAUA
35001
5301 SP
0010
OSASCO
550001
80001 SP
0001
SAO PAULO
9000000
500000 SP
0002
BRASILIA
890
50000 DF
0011
JK
10000
778 SP
0012
SEGUNDA_MAIOR
500001
300 RJ /* 2.a
em habitantes */
0013
SEGUNDA_MENOR
15000
6500 RJ /* 2.a
em quantidade de ruas */
Prof. Satoshi Nagayama
maior
menor
maior
menor
Download

Aula 1 - Conhecendo o ambiente e iniciando um pequeno projeto