Você está na página 1de 11

Laboratrio de Banco de Dados II 1a Aula Stored Procedures

Stored procedures
Uma seqncia de comandos SQL pode ser agrupada, formando uma stored procedure. A sua execuo comandada, invocando-se o nome da stored procedure. No entanto, mais do que simplesmente um substituto ao agrupamento de comandos SQL. 1. Consideraes sobre stored procedure a) Se a seqncia de comandos submetida vrias vezes, no h a necessidade de submeter toda a seqncia novamente, bastando invocar o nome da procedure. mais econmico do ponto de vista de codificao. Quando preciso alterar alguma coisa, bastar alterar num nico ponto da procedure; No repetir as correes em todos os pontos em que a seqncia se repete dentro de uma aplicao. b) Os comandos so pr-compilados e armazenados no banco de dados em formato de execuo pelo banco de dados. Ou seja, no h a necessidade de recompilao do cdigo fonte sempre que a execuo for comandada. O gerenciador j fez uma anlise do cdigo fonte no momento da criao da procedure e no precisa repeti-la em todas as execues. A parte que precisa ser reavaliada na execuo 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 seqncia executada no escopo do servidor. Do contrrio, cada comando da seqncia enviado ao servidor e retornado ao requisitante antes do envio do prximo comando. Entre estes comandos podem ser transferidos dados em volume significativo em termos de resultados intermedirios ou mesmo finais a serem aplicados definitivamente no banco de dados. Dependendo do nmero de comandos, isto impacta no tempo de resposta. d) Existe um ganho na segurana. Voc no concede acesso s tabelas, mas concede somente o direito de execuo sobre as procedures, estabelecendo com mais rigor quais operaes o usurio pode executar. e) Os comandos de controle transacional podem ser deslocados para dentro do SGBD. Quando comandado pela aplicao, eventos de comunicao podem produzir bloqueios demorados sobre os recursos, por conexes aparentemente inativas. Neste aspecto especfico, a contrapartida pode ser o deslocamento de algumas regras de negcio para o SGBD. Este fato, por si s, pode no representar um problema, a menos que isto contribua para a sobrecarga do sistema ou afete conceitualmente a arquitetura da soluo. f) Podem ser passados parmetros de execuo. g) As aplicaes tornam-se menos portveis com a utilizao 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 cdigos proprietrios e no temos interesse em cobrir muitos aspectos especficos. As stored procedure so anlogas s procedures em Pascal ou function em C. Admitem parmetros de entrada/sada. Permitem a utilizao das construes SQL j estudadas, alm de outras, como comandos de controle do fluxo de execuo e loop e declarao de variveis. Vamos, rapidamente, rever alguns comandos vlidos no laboratrio: Declarao de variveis
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 condio qualquer expresso booleana pode ser utilizada, inclusive aquelas presentes na clusula where, como exists, etc...

Repetio:
while (condition) begin . . . end

Controle de fluxo numa estrutura de repetio:

1. break -- interrompe o fluxo de execuo de um loop. Nem sempre recomendado considerando a boa estruturao do cdigo fonte.
while (Boolean_condition) begin . . If (condition) break . . end

2. continue reinicia o loop sem executar os comandos seguintes dentro do loop. Nem sempre recomendado considerando a boa estruturao do cdigo fonte.
while (Boolean_condition) begin . . If (condition) continue . . end

Abandonar a execuo da stored procedure:


If (condition) begin ... return end

Atribuio de valores s variveis:


set @var1 = 10, @var2 = 'abcd adb', @var3 = 123.87

Atribuio s variveis de valores obtidos do banco de dados:


select @var1 = habitantes, @var2 = nome, @var3 = habitantes / 1000.0 from tb_cidades1 where codigo = 'A99999'

Atribuio s variveis de valores obtidos do banco de dados com a clusula TOP:

declare @codigo char(15) select top 1 @codigo = codigo from tb_cidades1 order by codigo -- nestes casos, importante a clusula de ordernao

Concateno de strings:

Utilizar o operador "||" (duplo smbolo pipe) Exemplo:


select 'abc' || '123' from dual; -- Oracle set @variavel = @variavel_1 || 'xyz' select @variavel = nome || sobre_nome from tb_cidades1 where codigo = 'A999999'

No Lab do nosso curso, voc pode tambm, indistintamente, utilizar o smbolo "+"
select 'abc' + '123' set @variavel = @variavel_1 + 'xyz' select @variavel = nome + sobre_nome from tb_cidades1 where codigo = 'A999999'

SQL opera conjuntos de registros/linhas No podemos presumir que os comandos afetam somente um registro. Pode afetar um conjunto vazio, unitrio ou com vrios elementos. Resultados podem no ser os esperados se voc no levar em conta a multiplicidade dos registros afetados. Por exemplo,
declare @codigo char(20) select @codigo = codigo from tb_cidades1

Se existem vrias linhas da tabela, qual o valor da varivel?

Obteno dos primeiros registros de uma consulta (Esclarecimento quanto clusula TOP) s vezes, estamos interessados somente nos primeiros registros de um conjunto que satisfazem s condies de seleo. Para isto utilizamos a clusula top n. Exemplo:
select top 5 * from tb_cidades1 select from where order top 2 codigo, nome tb_cidades1 nome = 'Santos' by nome

delete top 10 from tb_cidades1 delete top 10 from tb_cidades1 where nome = 'So Pdro update top 2 tb_cidades1 set habitantes = 100 where nome = 'Santos'

Como atribuir valores s variveis quanto se utiliza a clusula TOP:


declare @codigo char(15) select top 1 @codigo = codigo from tb_cidades1 order by codigo -- nestes casos, importante a clusula de ordernao

a) A tabela classificada em ordem crescente de cdigo; b) A primeira linha deste resultado obtida; c) O valor da coluna cdigo desta linha obtida atribudo varivel. Em outras palavras, uma maneira artificial de atribuir varivel o menor cdigo presente na tabela.

Verificao da existncia de registros selecionados ou afetados Existem vrias formas de verificao da existncia de registros que satisfazem a certa condio, ou mesmo se um comando SQL selecionou ou afetou registros. Em captulos posteriores, veremos outras formas de verificaes. No laboratrio, o SGBD disponibiliza uma varivel global que imediatamente aps o comando pode ser consultada para saber quantas linhas foram selecionadas, inseridas, alteradas ou removidas. A varivel tem o nome
@@rowcount

Por exemplo:
declare @codigo_cidade_corrente select top 1 @codigo_cidade_corrente = codigo, @qtd_habitantes_corrente = habitantes from tb_cidades1 where habitantes > @qtd_habitantes_corrente order by habitantes if (@@rowcount = 0) begin . . -- acabou... . . end

. . .

Comando para criao de stored procedure


create procedure pr_exemplo (lista de parmetros e respectivos tipos) as begin ....... comandos sql .... end

Comando para remoo de stored procedure


drop procedure pr_lista_cidade

Comando para emitir uma mensagem


print "Esta uma mensagem..."

Exemplo de criao 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_cidades1 where codigo = @cod_cid if (@@rowcount = 0) begin print "cidade no existe." return end select @cod_cid, @nome_cid select codigo, nome, habitantes qtd_ruas, estado from tb_cidades1 where codigo = @cod_cid -- fim do cdigo fonte end ;

4. Observaes sobre o exemplo a) Neste exemplo especfico, os resultados poderiam ser obtidos de forma mais simples. A codificao exemplifica as formas de utilizao de algumas estruturas. b) A ltima linha contm somente um comentrio --. c) Execute um comando de cada vez. Neste caso, todo o texto refere-se a um nico comando de criao de procedure. Se voc tentar executar mais que um comando, por exemplo, um drop procedure pr_lista_cidade seguido do cdigo fonte para a sua criao, ocorrer erro. Ser necessria a colocao do terminador de comando que no padro. Se voc utiliza a ferramenta do nosso ambiente, como o msql, o terminador ;. Se estiver utilizando o browser, no poder ser informado, porque o envio indica o trmino da sequncia de comandos. Ele depende da ferramenta cliente utilizada. No 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 atribuio de variveis realizada. Esta sintaxe no comum a todos os gerenciadores. e) Para executar a procedure, substitua os valores dos parmetros por algum que seja vlido, nas chamadas abaixo:
exec pr_lista_cidade 'aaa' exec pr_lista_cidade 'bbb'

Atividade
1. Tabela de trabalho Criar uma tabela, conforme a descrio abaixo, de nome
tb_cidades1

Coluna Codigo nome habitantes qtd_ruas estado

Tipo char(15) varchar(50) int int char(2)

Admite valores indefinidos No No No No No

2. Dados na tabela de trabalho Incluas dados na sua tabela, copiando da tabela de nome
tb_cidades_prof

3. Stored procedure Crie uma stored procedure de nome


pr_lista_dados_segunda_cidade

que faz o seguinte: a) b) c) d) Recebe como parmetro o cdigo de uma cidade que consta da tabela tb_cidades1 e um inteiro n > 0; Guarda em varivel o nmero de habitantes da cidade correspondente ao cdigo; Se a cidade no existir, emite uma mensagem e termina a execuo da procedure; Utilizando, adequadamente, a estrutura top m e considerando que a cidade recebida como parmetro est em i-sima posio em nmero de habitantes, mostra todos os dados de todas as cidades que esto na posio i + n em nmero de habitantes. Para isto, suponha que a classificao das cidades segue a

ordem crescente. Ou seja, a primeira cidade a que tem o menor nmero de habitantes; Voc ter que escolher adequadamente o valor m da clusula top m; Mostra as cidades classificadas em (i + n)-sima posio em nmero de habitantes considerando que a cidade cujo cdigo foi fornecido est na i-sima posio em nmero de habitantes; e) Seguindo raciocnio semelhante e supondo que a cidade recebida como parmetro est em j-sima posio em quantidade de ruas, esta mesma procedure deve mostrar todos os dados de todas as cidades que esto na posio j - n em quantidade de ruas. A classificao no ranking segue o mesmo critrio de ordenao considerado para o nmero de habitantes; Mostra as cidades classificadas em (j - n)-sima posio em quantidade de ruas considerando que a cidade cujo cdigo foi fornecido est na j-sima posio em quantidade de ruas; f) Observao: Na parte da apresentao, utilizar diretamente com top n, no produz o resultado esperado porque no sabemos quantas cidades tem o mesmo nmero de habitantes e ruas e satisfazem condio de posio no ranking; g) O mtodo empregado funcionalmente correto, no sentido de que apresenta os resultados esperados, no entanto, no a melhor maneira de tratar este problema, mesmo no mbito de SQL. Reflita sobre isto. Acompanhe as prximas aulas; h) Observao: Vrias cidades podem ter o mesmo nmero de habitantes e/ou quantidade de ruas.

4. Exemplo de dados para testes Suponha que existam as seguintes cidades apresentadas em duas ordenaes diferentes. a) Em ordem de habitantes:
codigo --------------0002 0020 0017 0015 0019 0011 0013 0007 0008 0006 0009 0005 0004 0012 0003 0022 0021 0014 0016 0018 0010 0001 nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----BRASILIA 890 50000 DF MINAS DE OURO 5500 400 PE TERCEIRA_MENOR2 6000 400 PR TERCEIRA_MENOR1 7000 400 MG TERCEIRA_MENOR3 9000 400 AM 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 SEGUNDA_MAIOR 500001 300 RJ TAGUATINGA 500001 32433 DF FEIRA LIVRE 520000 90000 SC RIO BONITO 540000 6000 CE TERCEIRA_MAIOR2 540000 450 SP TERCEIRA_MAIOR3 540000 450 RS TERCEIRA_MAIOR4 540000 450 RJ OSASCO 550001 80001 SP SAO PAULO 9000000 500000 SP

b) Em ordem de quantidade de ruas


codigo --------------0012 0020 0015 0017 0019 0014 0016 0018 0006 0011 0009 0021 0007 0013 0008 0005 0003 0002 0004 0010 0022 0001 nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----SEGUNDA_MAIOR 500001 300 RJ MINAS DE OURO 5500 400 PE TERCEIRA_MENOR1 7000 400 MG TERCEIRA_MENOR2 6000 400 PR TERCEIRA_MENOR3 9000 400 AM TERCEIRA_MAIOR2 540000 450 SP TERCEIRA_MAIOR3 540000 450 RS TERCEIRA_MAIOR4 540000 450 RJ SAO CARLOS 34235 501 SP JK 10000 778 SP MAUA 35001 5301 SP RIO BONITO 540000 6000 CE CEILANDIA 27000 6500 DF SEGUNDA_MENOR 15000 6500 RJ BRASLANDIA 28000 8509 DF SAO CAETANO 47000 8600 SP TAGUATINGA 500001 32433 DF BRASILIA 890 50000 DF SANTO ANDRE 300001 50001 SP OSASCO 550001 80001 SP FEIRA LIVRE 520000 90000 SC SAO PAULO 9000000 500000 SP

5. Teste 1
exec pr_lista_dados_segunda_cidade '0009', 2 /* Mau */ cidade recebida codigo --------------0009 como parametro: nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----MAUA 35001 5301 SP

Cidades na classificao 2 superior em habitantes em relacao a 0009 codigo nome habitantes qtd_ruas estado --------------- ------------------------------ ----------- ----------- -----0004 SANTO ANDRE 300001 50001 SP Cidades na classificao 2 inferior em quantidade de ruas em relacao a 0009 codigo nome habitantes qtd_ruas estado --------------- ------------------------------ ----------- ----------- -----0006 SAO CARLOS 34235 501 SP

6. Teste 2
exec pr_lista_dados_segunda_cidade '0005', 2 /* So Caetano */ cidade recebida codigo --------------0005 como parametro: nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----SAO CAETANO 47000 8600 SP

Cidades na classificao 2 superior em habitantes em relacao a 0005 codigo --------------0003 0012 nome habitantes qtd_ruas ------------------------------ ----------- ----------TAGUATINGA 500001 32433 SEGUNDA_MAIOR 500001 300 estado -----DF RJ

Cidades na classificao 2 inferior em quantidade de ruas em relacao a 0005 codigo --------------0007 0013 nome habitantes qtd_ruas ------------------------------ ----------- ----------CEILANDIA 27000 6500 SEGUNDA_MENOR 15000 6500 estado -----DF RJ

7. Teste 3
exec pr_lista_dados_segunda_cidade '0011', 3 /* JK */ cidade recebida codigo --------------0011 como parametro: nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----JK 10000 778 SP

Cidades na classificao 3 superior em habitantes em relacao a 0011 codigo nome habitantes qtd_ruas estado --------------- ------------------------------ ----------- ----------- -----0008 BRASLANDIA 28000 8509 DF Cidades na classificao 3 inferior em quantidade de ruas em relacao a 0011 codigo --------------0015 0017 0019 0020 nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----TERCEIRA_MENOR1 7000 400 MG TERCEIRA_MENOR2 6000 400 PR TERCEIRA_MENOR3 9000 400 AM MINAS DE OURO 5500 400 PE

7. Teste 4
exec pr_lista_dados_segunda_cidade '0004', 3 /* Santo Andre */ cidade recebida codigo --------------0004 como parametro: nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----SANTO ANDRE 300001 50001 SP

Cidades na classificao 3 superior em habitantes em relacao a 0004 codigo --------------0014 0016 0018 0021 nome habitantes qtd_ruas estado ------------------------------ ----------- ----------- -----TERCEIRA_MAIOR2 540000 450 SP TERCEIRA_MAIOR3 540000 450 RS TERCEIRA_MAIOR4 540000 450 RJ RIO BONITO 540000 6000 CE

Cidades na classificao 3 inferior em quantidade de ruas em relacao a 0004 codigo nome habitantes qtd_ruas estado --------------- ------------------------------ ----------- ----------- -----0005 SAO CAETANO 47000 8600 SP

Prof. Satoshi Nagayama