Sei sulla pagina 1di 21

1

vou mostrar como se faz para criar stored procedures

Bom, vamos aos exemplos.

e funes no MySQL. Stored procedures e funes

Criando uma Stored Procedure

so processos que voc cria e ficam armazenados

Vamos supor que voc queira uma tabela para

noMySQL, onde voc pode execut-los depois. A

armazenar quais sesses de uma aula e quantas

vantagem que o tempo de execuo para consultar

vezes um aluno as acessou. Voc armazena em uma

dados e mostrar na tela do usurio, ou executar

tabela a nota do aluno para cada vez que ele faz os

comandos mais complexos, ficam muito mais rpidos

exerccios de cada aula.

do que se voc fosse fazer via PHP, por exemplo.

Ento temos as tabelas aula_sessao e aula_nota


(alm das tabelas aluno e aula, claro)

Imagina se voc tem que fazer uma consulta, e de

Voc precisa atualizar a tabela de sesso dos

acordo com cada resultado desta consulta voc tem

exerccios para cada aula que o usurio fez, dizendo

que inserir ou atualizar uma outra tabela. Ou ento

o nmero de vezes que o usurio fez os exerccios

imagine que voc tenha que fazer uma consulta e

daquela aula.

executar alguns clculos com os dados de alguns

Claro que voc pode criar um Trigger para executar

campos. Isso d para fazer com PHP, mas voc torna

isso automaticamente, mas imagina se voc comeou

o processo muito mais lento, pois para cada

a monitorar os dados de sesso da aula um tempo

resultado, o php abre uma nova consulta para

depois que o site j estava no ar. Voc vai ter que

executar a instruo devida. No exemplo que

recuperar os dados de algum lugar para a contagem

mostrarei, vou comparar uma stored procedure com

no comear do zero. E para agravar ainda mais a

um script php, que fazem exatamente a mesma coisa.

situao, voc resolveu atualizar estes dados depois


que o sistema de monitoramento j estava no ar, ou

Com uma stored procedure, voc faz uma chamada

seja, j possuia dados gravados. Ento voc tem que

s ao servidor MySQL e ele se encarrega de fazer

inserir novos registros se ainda no existirem, ou

sozinho. Stored Procedure so timas para se

atualizar os registros se j existirem.

executar scripts mais complexos no banco de dados.


Com uma funo, em uma nica consulta voc j traz
os resultados prontinhos para o php somente mostrar
na tela. como se o resultado da funo fosse um

view source
print?
0
delimiter ;
1

dado j armazenado mo MySQL.

0
2

-- Na linha abaixo eu apago a procedure

Diferena entre stored procedures e funes

03

drop procedure if exists insereDados;

caso ela exista

04
Stored procedures no retornam dados. Elas

05

delimiter |

executam scripts no MySQL, que podem ser desde

06

-- Na linha abaixo eu crio a procedure

alteraes da estrutura de tabelas, at migrao de

07

dados de uma tabela para outra, ou executar aes

08

de acordo com os resultados de uma consulta.

09
10

create procedure insereDados()


begin

-- Abaixo eu declaro as variveis.

Funes obrigatoriamente devem retornar dados,

11

DECLARE done INT DEFAULT 0;

sejam INT, CHAR, VARCHAR, BOOLEAN etc. So

12

declare aulaId INT;

timas para fazer comparao de dados e retornar

13

declare alunoId INT;

valores, executar clculos, consultar outras tabelas

14

declare vezes INT;

diferentes de acordo com os parmetros passados

15

etc.

16

Enfim, d para fazer muita coisa com o MySQL

1
7

atravs de Stored procedures e funes, que


otimizam o cdigo e o torna muito mais profissional.

declare existe CHAR(1);

-- Abaixo, eu declaro um cursor que ser a


minha consulta de referncia que atualizar
a tabela aula_sessao

2
1
8

-- Nela eu pego o id da aula, o id do

aluno, a quantidade de vezes que o aluno

4
9

fez os exerccios para cada aula,


1
9

-- e verifico em uma subquery se o aluno j


possui o registro daquela aula em
aula_sessao

2
0
21

23

select

24

a.idaula,

25

a.idaluno,

26

count(*),

2
7

a.idaluno,a.idaula

33

);

34
-- Na linha abaixo, altero o valor da

DECLARE CONTINUE HANDLER FOR NOT FOUND SET


done = 1;

vezes where idaula = aulaId and idaluno =


alunoId;
end if;
end if;
-- at que a variavel done receba o valor
TRUE (quando no existirem resultados
disponveis)

5
8
5
9

UNTIL done END REPEAT;


-- Fecho o cursor e finalizo a stored
procedure
CLOSE curs;

62

end

63

64
-- Ativo o cursor
OPEN curs;

65

delimiter ;

Para executar a procedure, basta cham-la assim:


CALL insereDados();

-- Comeo o loop para cada resultado

Se voc quiser apag-la depois de executada, bas dar

encontrado no cursor

o comando:

REPEAT

drop procedure if exists insereDados;


A mesma coisa no PHP (porm muito mais lento)
O cdigo PHP abaixo faz exatamente a mesma coisa

-- Atribuo os dados de cada campo, na ordem


do select do cursor, dentro das variveis
abaixo
FETCH curs INTO aulaId, alunoId, vezes,
existe;

4
6

update aula_sessao set sessao_exercicios =

61

4
3

4
7

5
4

resultado seja encontrado no cursor;

40

4
5

relacionando o aluno tabela aula_sessao,


elseif existe = 'S' then

6
0

39

4
4

-- Se j existe um registro

5
3

varivel done para um, caso nenhum

37

4
2

(aulaId,usuarioId,vezes);

5
7

32

4
1

(idaula,idaluno,sessao_exercicios) values

56

group by

38

insert into aula_sessao

55

from

30

3
6

5
1

aula_sessao where idaluno = a.idaluno and

aula_nota a

3
5

if existe = 'N' then

vou atualizar o registro

(select if(count(*)=0,'N','S') from

29
31

5
0

5
2

idaula = a.idaula)
2
8

no existe o dado em aula_sessao, vou


inserir o registro

DECLARE curs CURSOR FOR (

22

-- se o resultado do cursor diz que

que a Stored Procedure que criamos:


view source
print?
01

<?php

02
03

$sql = "

-- se done falso (done = 0) executa o que

04

select

est dentro do if

05

a.idaula,

06

a.idaluno,

if not done then

3
07

count(*) as vezes,

Vamos supor que voc tem uma tabela de usurios

08

if(s.id is null,'N','S') as existe

que te traz o nivel de acesso de cada um deles.

09

from

Vamos supor que temos os seguintes nveis de

10

aula_nota a

acessos:

1
1
1
2

left join aula_sessao s on s.idaula =


a.idaula and s.idaluno = a.idaluno

3: administrador
a.idaluno,a.idaula

14

";

15

Voc quer apresentar esta informao para o usurio.


Para fazer isso somente uma vez, basta na sql voc

$res = mysql_query( $sql );

16

fazer:
view source

17

while( $r = mysql_fetch_array( $res ) )

18

19

if($r['existe']=="S")

20

2
2

1: colaborador
2: moderador

group by

13

2
1

0: comum

$sql = "update aula_sessao set

print?
01
02

idusuario,

03

nome,

sessao_exercicios = ".$r['vezes']." where

04

idaula = ".$r['idaula']." and idusuario =

05

".$r['idaluno'];

06

when 2 then 'moderador'


when 3 the 'administrador'

09

10

$sql = "insert into aula_sessao

11

$r['vezes'].")";
2
6

from

12

usuario

13

where idusuario = 1

a string que diz o nivel de acesso do usurio, com a


mysql_query( $sql );
}

vantagem de poder us-la em vrias sqls, sem ter a


necessidade de fazer o CASE toda vez que voc
precisar obter esse dado. Alm disso, a manuteno

29
30

end) as nivelString

Voc pode simplesmente criar uma funo para pegar

27
28

when 0 then 'comum'


when 1 then 'colaborador'

else

(".$r['idaula'].",".$r['idaluno'].",".

(case nivel

08

24

(idaula,idaluno,sessao_exercicios) values

email,

07

23
2
5

select

?>

A desvantagem que a cada vez que voc d o


comando mysql_query(), uma nova conexo aberta
com o banco. Ento, se o resultado da primeira query
tem muitas linhas, o tempo de execuo ser muito
grande, o uso de processador ser absurdo, voc
poder perder dados durante o tempo de execuo
do script, alm de poder derrubar o servidor MySQL
(acontece muito na plataforma windows ou de
acordo com as configuraes do servidor).
Usando a Stored Procedure, alm da velocidade de
execuo ser absurdamente maior, voc mantm a
consistncia de dados, pois o MySQL sabe se algum
dado foi inserido durante a execuo do script e o
atualiza tambm, se for o caso.
Criando uma funo no MySQL
Vou mostrar um exemplo simples para ilustrar.

fica muito mais simples se voc quiser, por exemplo,


acrescentar mais um nvel de acesso. Basta alterar a
funo.
Ento vamos criar:
view source
print?
01

delimiter ;

02
03

drop function if exists getNivelString;

04
05

delimiter |

06
07
08
09
10

create function getNivelString(nivel INT)


returns varchar(45)
begin
declare nivelString varchar(45);

4
11

case nivel

12

when 0 then nivelString = 'comum'

1
3

when 1 then nivelString =


'colaborador'

1
4

{$campo['nivelString']}.

15

";

A mesma coisa em PHP


view source

when 2 then nivelString = 'moderador'

1
5

when 3 then nivelString =

02

'administrador'

1
6

print?
01
<?php

else nivelString = 'comum'

function getNivelString($idnivel)

03

04

17

end;

18

return nivelString;

05
end

20

0
7

delimiter ;

0
8

21
Agora, a consulta pode ficar assim:
view source

06

19

22

switch( $idnivel )

0
9

case 0: $string = 'comum'; break;


case 1: $string = 'colaborador';
break;
case 2: $string = 'moderador'; break;
case 3: $string = 'administrador';
break;

1
0

print?
1

default $string = 'comum'

select

11

idusuario,

12

return $string;

nome,

13

email,

5
6

getNivelString(idnivel) as nivelString
from

7
8

usuario
where idusuario = 1

14
1
5

$sql = "select idusuario, nome, email,

1
6

$campo =

Lembrando que este um exemplo bem simples

17

diante da infinidade de coisas que se pode fazer.

18

Agora, o php para mostar os dados fica bem simples:

1
9

view source

idnivel from usuario where idusuario = 1";


mysql_fetch_array( mysql_query( $sql ) );

echo "
Ol {$campo['nome']}! Voc um usurio
" . getNivelString( $campo['idnivel'] ) .
".

print?
01

$sql = "

02

select

03

idusuario,

04

nome,

05

email,

06

getNivelString(idnivel) as nivelString

07

from

08

usuario

09

where idusuario = 1

10

";

1
1

$campo =
mysql_fetch_array( mysql_query( $sql ) );

1
2
1
3
1

2
0

";

21

?>

Os exemplos dados aqui so apenas para demostrar


como criar e usar funes e stored procedures no
MySQL. Os exemplos so simples, mas voc pode
adapt-los s suas necessidades.

Stored Procedures no MySQL


Neste artigo (usarei um servidor SUPERION da SunSix, rodando
Ubuntu 6.06 LTS com MySQL 5.0.37 Community Version),

echo "
Ol {$campo['nome']}! Voc um usurio

iniciaremos uma viagem interessante sobre todo o mundo dos


procedimentos armazenados ou stored routines, cujo conceito
principal que so "programas armazenados no servidor, pr-

5
compilados, chamados de forma explcita para executar alguma

IN => este um parmetro de entrada, ou seja, um


parmetro cujo seu valor ser utilizado no interior do
procedimento para produzir algum resultado;

OUT => est parmetro retorna algo de dentro do


procedimento para o lado externo, colocando os valores
manipulados disponveis na memria ou no conjunto de
resultados;

INOUT => faz os dois trabalhos ao mesmo tempo!

lgica de manipulao de dados, podendo retornar ou no algum


valor".
Mal comeamos e j temos o conceito de stored procedure ou
stored routines. No caso do MySQL, os procedimentos
armazenados esto disponveis exatamente desde a verso 5.0,
que foi um marco na evoluo do SGBD OpenSource mais utilizado
no mundo.
Necessariamente, voc precisar ter instalado na sua mquina o

parameters: nessa parte do procedimento, informaremos os

MySQL 5++ e o MySQL Client (este disponibilizado no momento

parmetros da seguinte forma: [IN | OUT | INOUT] nome_parametro

da instalao do server) . Utilizarei tambm o MySQL Query

tipo_dado.

Browser para tornar nossa experincia mais interessante com o


MySQL e sair um pouco da linha de comando, mas anda grade

characteristics: as caractersticas do procedimento pode apresentar.

parte ser utilizando o mysql client.

Como no utilizaremos inicialmente tais caractersticas, vamos nos


ater a sintaxe principal. Questes de segurana, se determinstica

Antes de entrarmos na sintaxe, ainda temos que registrar aqui que

ou no, qual a linguagem que estamos utilizando e se nosso

os procedimentos armazenados, quando criados e compilados, so

procedimento modificar dados na banco de dados, so algumas

inseridos em uma tabela chamada ROUTINES no banco de dados

das caractersticas que poderemos definir neste item que

INFORMATION_SCHEMA, que o dicionrio de dados do MySQL.

abordaremos com mais detalhe na parte dois do artigo.

Para listarmos todos os stored routines (Stored Procedure e


Functions), basta emitirmos o seguinte comando no mysql client:

corpo_da_rotina: onde so definidos os comandos SQL que faro


alguma manipulao e/ou defendero alguma lgica, podendo

mysql> SELECT * FROM INFORMATION_SCHEMA.ROUTINES;

retornar ou no algum resultado.

Perceba que listamos todos os procedimentos armazenados (Stored

PRIMEIRO EXEMPLO:

Procedure e Functions), de todos os bancos de dados. Saliento que


estamos listando somente Stored Procedure e Functions, pois,

Nesse primeiro exemplo, implementaremos um Stored Procedure

somente estas rotinas so gravadas na tabela ROUTINES do

bem simples, que nos devolver um "OL"! Abra um terminal do

bancos de dados INFORMATION_SCHEMA. Triggers tambm so

seu Linux ou mesmo um prompt do seu Windows e entre no mysql

um tipo de procedimento armazenado, mas esto separadas em

client digitando:

outra tabela do dicionrio, chamada TRIGGERS.


shell> mysql -u nome_usuario -psenha,
mysql> SELECT * FROM INFORMATION_SCHEMA.TRIGGERS;
A sintaxe geral para criao de Stored Procedure a seguinte:

Usarei neste artigo o banco de dados chamado test, que j vem


criado desde a instalao do MySQL. Caso no conste no seu, use
um banco de dados de sua preferncia.

CREATE PROCEDURE proc_name([parameters, ...])


[characteristics]
[BEGIN]

Caso prefira, podemos usar tambm o MySQL Query Browser (voc


poder baix-lo em http://dev.mysql... dentro de um pacote
chamado GUI Tools). No Windows basta instalar e no Linux basta

corpo_da_rotina;
[END]
Explicando...
proc_name: seu procedimento armazenado deve ter um nome, para
quando for chamado, podermos ento us-lo;
tipo_param: existem 3 tipos de parmetros em uma Stored
Procedure no MySQL:

descompactar o pacote TAR e executar.


Se voc optou pelo MySQL Client, nesse momento estamos nesse
ponto:

Delimite
MySQL
Client

r
Bem, procedimento compilado basta executarmos o procedimento

Se voc tiver optado por trabalhar com o MySQL Query Browser,


estamos nesse ponto:

com o seguinte comando:


CALL OLA();
OBS.: Aps a verso 5.1.18, no mais necessrio os parnteses
caso o procedimento no receba parmetros.
A resposta do procedimento ser "OL!" como definimos.

MySQL
Query Browser
Pronto! O Query Browser j nos deu quase tudo pronto para
escrevermos somente os parmetros que teremos no nosso
procedimento e o corpo da rotina. Notem que utilizado o operador
DELIMITER para mudar o delimitador de comandos, que por
padro o ";". Mudamos o DELIMITADOR para podermos usar o ";"
no meio do procedimento. Caso no efetuemos essa troca, o
procedimento ser enviado pela metade e um erro ser enviado ao
terminal, por erro na sintaxe.
DELIMITADOR no MySQL, em outras situaes, por padro
tambm chamado de terminador. Para verificar qual o
delimitador da sesso corrente emita o comando \s, que a forma
curta do comando STATUS.

Respos
ta
Bom, agora que j temos uma noo bsica de como
implementado um procedimento armazenado no MySQL, j
podemos partir para aplicaes do mundo real, tais como,
manipular inseres de dados, excluses de registros e
atualizaes de linhas de uma ou mais tabelas. Tudo isso nos
levar a aportar l na frente no conceito de transaes, onde
desenvolveremos um procedimento para simulao de transferncia
de valor entre contas bancrias de mesma agncia.
Como seria ento, um procedimento para inserir dados em uma
tabela do banco de dados?

7
Bom, antes de prosseguirmos, criaremos uma tabela, de nome
tbl_correntista, que ter os campos correntista_id do tipo INT,
correntista_nome do tipo VARCHAR(60) e correntista_cpf do tipo
VARCHAR(20).
CREATE TABLE tbl_correntista (
correntista_id int auto_increment primary key,
correntista_nome varchar(60) not null unique,
correntista_cpf varchar(20) not null,
dt_cadastro timestamp default current_timestamp,
) Engine =InnoDB;
Pronto! Aps executarmos o script acima nossa tabela estar criada
e j poderemos dar carga atravs de um procedimento
armazenado, onde tambm utilizaremos em meio a este, estruturas
condicionais, IF-THEN-ELSE!

T
abelaTabela

Com a nossa tabela criada, criaremos nosso procedimento para


efetuar o INSERT dos dados, ou seja, um procedimento para dar
carga na tabela.

Temos mais dois procedimentos, fceis, para complementar essa


primeira parte do artigo. Faremos a seguir, um procedimento, com o
mesmo formato para atualizarmos o registro da nossa tabela

DELIMITER //
CREATE PROCEDURE mySp_correntistaInsert(v_nome
VARCHAR(60), v_cpf VARCHAR(20))
BEGIN
IF ((v_nome != '') && (v_cpf != '')) THEN
INSERT INTO tbl_correntista (correntista_nome,
correntista_cpf)
VALUES (v_nome, v_cpf);
ELSE
SELECT 'NOME e CPF devem ser fornecidos para o
cadastro!' AS Msg;

"tbl_correntista", que at o momento encontra-se com um registro.


Sero trs agora, o identificador do registro - v_id - , o novo nome
do correntista - v_nome - e o novo cpf - v_cpf -.
Vamos l!
DELIMITER //
CREATE PROCEDURE mySp_correntistaUpdate(v_id INT,
v_nome VARCHAR(60), v_cpf VARCHAR(20))

END IF;

BEGIN

END;

IF (((v_id > 0) && (v_id != '') ) && (v_nome != '') && (v_cpf != ''))
THEN

//
Aps compilarmos o procedimento, j poderemos cham-lo atravs

UPDATE tbl_correntista SET correntista_nome =v_nome,

da declarao CALL, como se segue:

correntista_cpf =v_cpf

CALL mySp_correntistaInsert('Wagner Bianchi', '023.456.789-10');

WHERE correntista_id =v_id;

...notem que utilizamos em meio ao nosso procedimento de

ELSE

insero, a estrutura condicional para consistir o valor das variveis.


SELECT 'O novos NOME e CPF devem ser informados!' AS Msg;

Caso os valores de ambas sejam vazios, a mensagem ser


disparada, como segue abaixo:

END IF;
END;
//
J podemos, aps compilarmos o procedimento de UPDATE,
atualizarmos nosso registro na tabela de correntistas. Depois de
compilado com sucesso, j podemos chamar nosso procedimento
Mensag

em
Aps executarmos a linha de insero com os valores, teremos um
registro na tabela, da seguinte forma:

de atualizao e passar os parmetros para atualizar o registro que


temos na tabela.
CALL mySp_correntistaUpdate(1, 'Wagner MySQL Bianchi',
'123.123.111-11');

8
principalmente para sistemas que necessitam de modularidade e
otimizao quanto performance.
Por outro lado, voc poder ficar preso ao MySQL (que no mal
negcio) ou qualquer outro SGBD que voc v usar para ser backend, utilizando os procedimentos armazenados.
Na parte 02, continuao deste artigo, avanaremos bem nos
TabelaT
abela
Note que este procedimento poder facilmente ser adaptado em
qualquer sistema que receba o identificador do registro a ser
atualizado em uma tabela qualquer de um banco de dados.
Sistemas web passam parmetros com facilidade vi POST ou GET,

conceitos e j falaremos de transaes com vrios comandos


dentro de uma Stored Procedures ou Stored Routines, trabalhando
com criao de variveis, iteraes e savepoints, iniciando nossa
aplicao de transferncia de valores entre contas bancrias de
mesma agncia, que tambm necessitar uma pequena introduo
nos conceitos de commit e rollback. Ou seja, transao.
ed by Heitor Pimentel

de forma que podero ser entregues como parmetro ao


procedimento.

Ol pessoal!

Para finalizarmos, faremos um procedimento para excluir registros,

Gostaria, antes de mais nada, agradecer ao pessoal do iMasters pelo convite


e salientar aqui que me sinto muito feliz com mais esse advento.

que o mais trivial de todos, basta mais uma vez enviarmos o


identificador do registro como parmetro e efetuarmos a excluso
aps a conferncia como estamos fazendo nos outros
procedimentos.
Note que, em um sistema, voc poder implementar um nico
procedimento para excluso de registros, que receber alguns

Neste artigo (usarei um servidor SUPERION da SunSix, rodando Ubuntu


6.06 LTS com MySQL 5.0.37 Community Version), iniciaremos uma
viagem interessante sobre todo o mundo dos procedimentos armazenados
ou stored routines, cujo conceito principal que so programas
armazenados no servidor, pr-compilados, chamados de forma explcita
para executar alguma lgica de manipulao de dados, podendo retornar
ou no algum valor.

parmetros como o identificador, o nome da tabela e o nome da


coluna, mas, nesse momento, nos atentaremos para o simples, nos
prximos artigos sofisticaremos um pouco mais nossos
procedimentos.
DELIMITER //
CREATE PROCEDURE mySp_correntistaDelete(v_id INT)
BEGIN
IF ((v_id > 0) && (v_id != '')) THEN
DELETE FROM tbl_correntista WHERE correntista_id
=v_id;
ELSE
SELECT 'O identifiador do registro no foi informado!' AS Msg;
END IF;
END;

Mal comeamos e j temos o conceito de stored procedure ou stored


routines. No caso do MySQL, os procedimentos armazenados esto
disponveis exatamente desde a verso 5.0, que foi um marco na evoluo
do SGBD OpenSource mais utilizado no mundo.
Necessariamente, voc precisar ter instalado na sua mquina o MySQL 5+
+ e o MySQL Client (este disponibilizado no momento da instalao do
server) . Utilizarei tambm o MySQL Query Browser para tornar nossa
experincia mais interessante com o MySQL e sair um pouco da linha de
comando, mas anda grade parte ser utilizando o mysql client.
Antes de entrarmos na sintaxe, ainda temos que registrar aqui que os
procedimentos armazenados, quando criados e compilados, so inseridos
em uma tabela chamada ROUTINES no banco de dados
INFORMATION_SCHEMA, que o dicionrio de dados do MySQL. Para
listarmos todos os stored routines (Stored Procedure e Functions), basta
emitirmos o seguinte comando no mysql client:

//
Agora j podemos excluir o registro que inserimos e atualizamos!

mysql> SELECT * FROM INFORMATION_SCHEMA.ROUTINES;

Segue a sintaxe para isso:

Perceba que listamos todos os procedimentos armazenados (Stored


Procedure e Functions), de todos os bancos de dados. Saliento que estamos
listando somente Stored Procedure e Functions, pois, somente estas rotinas
so gravadas na tabela ROUTINES do bancos de dados
INFORMATION_SCHEMA. Triggers tambm so um tipo de
procedimento armazenado, mas esto separadas em outra tabela do
dicionrio, chamada TRIGGERS.

CALL mySp_correntistaDelete(1);
Bom, espero que este artigo, ainda na primeria fase, com
aplicaes de procedimentos muito bsicos, possam trazer uma
iniciao em stored procedure no MySQL a todos que buscam
aprender a manejar este recurso que de grande proveito,

mysql> SELECT * FROM INFORMATION_SCHEMA.TRIGGERS;

9
A sintaxe geral para criao de Stored Procedure a seguinte:
CREATE PROCEDURE proc_name([parameters, ...])
[characteristics]
[BEGIN]
corpo_da_rotina;
[END]
Explicando
proc_name: seu procedimento armazenado deve ter um nome, para quando
for chamado, podermos ento us-lo;
tipo_param: existem 3 tipos de parmetros em uma Stored Procedure no
MySQL:

IN => este um parmetro de entrada, ou seja, um


parmetro cujo seu valor ser utilizado no interior
do procedimento para produzir algum resultado;

OUT => est parmetro retorna algo de dentro do


procedimento para o lado externo, colocando os
valores manipulados disponveis na memria ou no
conjunto de resultados;

INOUT => faz os dois trabalhos ao mesmo tempo!

MySQL
Client
Se voc tiver optado por trabalhar com o MySQL Query Browser, estamos
nesse ponto:

parameters: nessa parte do procedimento, informaremos os parmetros da


seguinte forma: [IN | OUT | INOUT] nome_parametro tipo_dado.
characteristics: as caractersticas do procedimento pode apresentar. Como
no utilizaremos inicialmente tais caractersticas, vamos nos ater a sintaxe
principal. Questes de segurana, se determinstica ou no, qual a
linguagem que estamos utilizando e se nosso procedimento modificar
dados na banco de dados, so algumas das caractersticas que poderemos
definir neste item que abordaremos com mais detalhe na parte dois do
artigo.
corpo_da_rotina: onde so definidos os comandos SQL que faro alguma
manipulao e/ou defendero alguma lgica, podendo retornar ou no
algum resultado.
PRIMEIRO EXEMPLO:
Nesse primeiro exemplo, implementaremos um Stored Procedure bem
simples, que nos devolver um OL! Abra um terminal do seu Linux ou
mesmo um prompt do seu Windows e entre no mysql client digitando:
shell> mysql -u nome_usuario -psenha,
Usarei neste artigo o banco de dados chamado test, que j vem criado
desde a instalao do MySQL. Caso no conste no seu, use um banco de
dados de sua preferncia.
Caso prefira, podemos usar tambm o MySQL Query Browser (voc
poder baix-lo em http://dev.mysql dentro de um pacote chamado GUI
Tools). No Windows basta instalar e no Linux basta descompactar o pacote
TAR e executar.
Se voc optou pelo MySQL Client, nesse momento estamos nesse ponto:

MySQL
Query Browser
Pronto! O Query Browser j nos deu quase tudo pronto para escrevermos
somente os parmetros que teremos no nosso procedimento e o corpo da
rotina. Notem que utilizado o operador DELIMITER para mudar o
delimitador de comandos, que por padro o ;. Mudamos o
DELIMITADOR para podermos usar o ; no meio do procedimento. Caso
no efetuemos essa troca, o procedimento ser enviado pela metade e um
erro ser enviado ao terminal, por erro na sintaxe.
DELIMITADOR no MySQL, em outras situaes, por padro tambm
chamado de terminador. Para verificar qual o delimitador da sesso
corrente emita o comando \s, que a forma curta do comando STATUS.

10
CREATE TABLE tbl_correntista (
correntista_id int auto_increment primary key,
correntista_nome varchar(60) not null unique,
correntista_cpf varchar(20) not null,
dt_cadastro timestamp default current_timestamp,
) Engine =InnoDB;
Pronto! Aps executarmos o script acima nossa tabela estar criada e j
poderemos dar carga atravs de um procedimento armazenado, onde
tambm utilizaremos em meio a este, estruturas condicionais, IF-THENELSE!
Com a nossa tabela criada, criaremos nosso procedimento para efetuar o
INSERT dos dados, ou seja, um procedimento para dar carga na tabela.

Delimite
r
Bem, procedimento compilado basta executarmos o procedimento com o
seguinte comando:
CALL OLA();
OBS.: Aps a verso 5.1.18, no mais necessrio os parnteses caso o
procedimento no receba parmetros.

DELIMITER //
CREATE PROCEDURE mySp_correntistaInsert(v_nome
VARCHAR(60), v_cpf VARCHAR(20))
BEGIN
IF ((v_nome != '') && (v_cpf != '')) THEN
INSERT INTO tbl_correntista (correntista_nome,
correntista_cpf)
VALUES (v_nome, v_cpf);
ELSE
SELECT 'NOME e CPF devem ser fornecidos para o
cadastro!' AS Msg;
END IF;
END;
//
Aps compilarmos o procedimento, j poderemos cham-lo atravs da
declarao CALL, como se segue:
CALL mySp_correntistaInsert(Wagner Bianchi, 023.456.789-10);

A resposta do procedimento ser OL! como definimos.


notem que utilizamos em meio ao nosso procedimento de insero, a
estrutura condicional para consistir o valor das variveis. Caso os valores
de ambas sejam vazios, a mensagem ser disparada, como segue abaixo:

Mensage
m

Resposta
Bom, agora que j temos uma noo bsica de como implementado um
procedimento armazenado no MySQL, j podemos partir para aplicaes
do mundo real, tais como, manipular inseres de dados, excluses de
registros e atualizaes de linhas de uma ou mais tabelas. Tudo isso nos
levar a aportar l na frente no conceito de transaes, onde
desenvolveremos um procedimento para simulao de transferncia de
valor entre contas bancrias de mesma agncia.
Como seria ento, um procedimento para inserir dados em uma tabela do
banco de dados?
Bom, antes de prosseguirmos, criaremos uma tabela, de nome
tbl_correntista, que ter os campos correntista_id do tipo INT,
correntista_nome do tipo VARCHAR(60) e correntista_cpf do tipo
VARCHAR(20).

Aps executarmos a linha de insero com os valores, teremos um registro


na tabela, da seguinte forma:

11
Note que este procedimento poder facilmente ser adaptado em qualquer
sistema que receba o identificador do registro a ser atualizado em uma
tabela qualquer de um banco de dados. Sistemas web passam parmetros
com facilidade vi POST ou GET, de forma que podero ser entregues como
parmetro ao procedimento.
Para finalizarmos, faremos um procedimento para excluir registros, que o
mais trivial de todos, basta mais uma vez enviarmos o identificador do
registro como parmetro e efetuarmos a excluso aps a conferncia como
estamos fazendo nos outros procedimentos.

T
abelaTabela
Temos mais dois procedimentos, fceis, para complementar essa primeira
parte do artigo. Faremos a seguir, um procedimento, com o mesmo formato
para atualizarmos o registro da nossa tabela tbl_correntista, que at o
momento encontra-se com um registro. Sero trs agora, o identificador do
registro v_id , o novo nome do correntista v_nome e o novo cpf
v_cpf -.
Vamos l!
DELIMITER //
CREATE PROCEDURE mySp_correntistaUpdate(v_id INT,
v_nome VARCHAR(60), v_cpf VARCHAR(20))
BEGIN
IF (((v_id > 0) && (v_id != '') ) && (v_nome !=
'') && (v_cpf != '')) THEN
UPDATE tbl_correntista SET correntista_nome
=v_nome,
correntista_cpf =v_cpf
WHERE correntista_id =v_id;
ELSE
SELECT 'O novos NOME e CPF devem ser informados!'
AS Msg;
END IF;
END;
//
J podemos, aps compilarmos o procedimento de UPDATE, atualizarmos
nosso registro na tabela de correntistas. Depois de compilado com sucesso,
j podemos chamar nosso procedimento de atualizao e passar os
parmetros para atualizar o registro que temos na tabela.
CALL mySp_correntistaUpdate(1, Wagner MySQL Bianchi,
123.123.111-11);

Note que, em um sistema, voc poder implementar um nico


procedimento para excluso de registros, que receber alguns parmetros
como o identificador, o nome da tabela e o nome da coluna, mas, nesse
momento, nos atentaremos para o simples, nos prximos artigos
sofisticaremos um pouco mais nossos procedimentos.
DELIMITER //
CREATE PROCEDURE mySp_correntistaDelete(v_id INT)
BEGIN
IF ((v_id > 0) && (v_id != '')) THEN
DELETE FROM tbl_correntista WHERE correntista_id
=v_id;
ELSE
SELECT 'O identifiador do registro no foi
informado!' AS Msg;
END IF;
END;
//
Agora j podemos excluir o registro que inserimos e atualizamos! Segue a
sintaxe para isso:
CALL mySp_correntistaDelete(1);
Bom, espero que este artigo, ainda na primeria fase, com aplicaes de
procedimentos muito bsicos, possam trazer uma iniciao em stored
procedure no MySQL a todos que buscam aprender a manejar este recurso
que de grande proveito, principalmente para sistemas que necessitam de
modularidade e otimizao quanto performance.
Por outro lado, voc poder ficar preso ao MySQL (que no mal negcio)
ou qualquer outro SGBD que voc v usar para ser back-end, utilizando os
procedimentos armazenados.
Na parte 02, continuao deste artigo, avanaremos bem nos conceitos e j
falaremos de transaes com vrios comandos dentro de uma Stored
Procedures ou Stored Routines, trabalhando com criao de variveis,
iteraes e savepoints, iniciando nossa aplicao de transferncia de
valores entre contas bancrias de mesma agncia, que tambm necessitar
uma pequena introduo nos conceitos de commit e rollback. Ou seja,
transao
MySQL TRIGGERS
Neste artigo, sero apresentados os principais conceitos
sobre os TRIGGERS e sua aplicabilidade.

Neste artigo, sero apresentados os principais


conceitos sobre os TRIGGERS e sua aplicabilidade.
Ta
belaTabela

Aps a conceituao, trabalharemos um estudo de


caso de um estoque de produtos, com baixa nas

12
quantidades atravs destes procedimentos

BEFORE ou AFTER, podemos ter um TRIGGER a ser

armazenados.

disparado para defender alguma lgica.

Aps ler este artigo, voc estar apto :

A sintaxe geral de definio de um TRIGGER a


seguinte:

- Definir o que um TRIGGER;


- Definir dados de antes (OLD) e depois (NEW);
- Criar um TRIGGER;
- Excluir um TRIGGER;
- Restries em relao TRIGGERS.
O que um TRIGGER?
- DEFINER: Quando o TRIGGER for disparado,
Um TRIGGER ou gatilho um objeto de banco de

esta opo ser checada para checar com quais

dados, associado a uma tabela, definido para ser

privilgios este ser disparado. Utilizar os

disparado, respondendo a um evento em particular.

privilgios do usurio informado em user

Tais eventos so os comandos da DML (Data

(wagner@localhost) ou os privilgios do usurio

Manipulation Language): INSERT, REPLACE, DELETE

atual (CURRENT_USER). Caso essa sentena seja

ou UPDATE. Podemos definir inmeros TRIGGERS

omitida da criao do TRIGGER, o valor padro

em uma base de dados baseados diretamente em

desta opo CURRENT_USER();

qual dos comandos acima ir dispar-lo, sendo que,


para cada um, podemos definir apenas um
TRIGGER. Os TRIGGERS podero ser disparados
para trabalharem antes ou depois do evento.

- trigger_name: define o nome do procedimento,


por exemplo, trg_test;
- trigger_time: define se o TRIGGER ser ativado

Veremos como definir o momento de atuao do

antes (BEFORE) ou depois (AFTER) do comando

TRIGGER mais frente.

que o disparou;
- trigger_event: aqui se define qual ser o

Utilizaremos a seguinte tabela da Figura 01 para


nossos testes:

evento, INSERT, REPLACE, DELETE ou UPDATE;


- tbl_name: nome da tabela onde o TRIGGER
ficar pendurado aguardando o trigger_event;
- trigger_stmt: as definies do que o o TRIGGER
dever fazer quando for disparado.
Definir dados de antes (OLD) e depois (NEW)
Em meio aos TRIGGERS temos dois operadores
importantssimos que nos possibilitam acessar as
colunas da tabela alvo do comando DML, ou seja,
podemos acessar os valores que sero enviados
para a tabela tbl_cliente antes (BEFORE) ou depois
(AFTER) de um UPDATE, por exemplo. Tais
operadores nos permitiro ento, ter dois
momentos, o antes e o depois e tambm examinar

Figura 01. Criando a tabela de testes tbl_cliente.


Baseado na tabela tbl_cliente, podemos definir os
TRIGGERS para serem disparados, por exemplo,
antes (BEFORE) ou depois (AFTER) de um INSERT.
Agora sabemos ento que para cada momento

os valores para que sejam ou no inseridos,


atualizados ou excludos da tabela.
Antes mesmo de analisarmos os operadores, temos
que analisar vejamos as seguintes diretrizes:

13
Ao tentarmos inserir um valor cujo nmero de
- INSERT: o operador NEW.nome_coluna, nos

caracteres menor ou igual a 0 ou nada, o

permite verificar o valor enviado para ser inserido

TRIGGER ser disparado e setar o valor enviado

em uma coluna de uma tabela. OLD.nome_coluna

para NULL atravs do operador NEW.nome_coluna.

no est disponvel.

Como na tabela de exemplo a coluna cliente_nome

- DELETE: o operador OLD.nome_coluna nos

foi configurada com a restrio NOT NULL, ou seja,

permite verificar o valor excludo ou a ser excludo.

no aceitar valores nulos, uma mensagem de erro

NEW.nome_coluna no est disponvel.

ser enviada e o INSERT falhar, como mostra a

- UPDATE: tanto OLD.nome_coluna quanto

Figura 03.

NEW.nome_coluna esto disponveis, antes


(BEFORE) ou depois (AFTER) da atualizao de uma
linha.
Percebemos ento que, ao inserir uma nova linha
em uma tabela, temos os valores das colunas
disponvel atravs do operador NEW.nome_coluna,
quando exclumos uma linha, temos ainda os
valores das colunas da linha excluda atravs do
operador OLD.nome_coluna e temos os dois
operadores disponveis no UPDATE e no REPLACE
pois as duas declaraes consistem em um DELETE
seguido por um INSERT. (REPLACE, este comando
apresenta outros detalhes a serem analisados
numa prxima oportunidade).
Criemos ento um primeiro TRIGGER, bem bsico
que no far nada mais que validar se os dados
foram passados em uma declarao INSERT antes
(BEFORE) que sejam cadastrados na tabela de
exemplo. Validaremos o nome com quantidade de
caracteres maior ou igual a 4 (quatro). (Figura 02)

Figura 03 O INSERT falhar aps uma tentativa


de inserir um valor no permitido.
Podemos criar uma restrio de integridade
referencial com TRIGGERS. Por exemplo, usaremos
tabelas MyISAM (que no do suporte a criao de
relacionamento com chaves estrangeiras) e,
aproveitando nosso exemplo, como clientes
compram produtos, podemos criar uma tabela de
produtos e restringir que somente os produtos
cadastrados podem ser comprados, inseridos na
tabela de compra e que somente clientes
cadastrados podem efetuar compras. Criemos
ento a tabela de produtos e compras, acompanhe
o seguinte modelo:

Perceba que o modelo no conta com


Figura 02 TRIGGER para conferir se o

relacionamentos, os quais defenderemos com

CHAR_LENTH() de nome maior que 4 (quatro).

TRIGGERS. Um INSERT que seja endereado


tabela tbl_compra (que tem as colunas cliente_id e

14
produto_id definidas como NOT NULL), disparar

uma outra tabela, por exemplo, uma tabela com a

um TRIGGER, tendo a responsabilidade de conferir

seguinte estrutura (Figura 06):

se o produto a ser inserido existe na tabela de


produtos e se o cliente que efetua a compra est na
tabela tbl_cliente. Vamos ao TRIGGER (Figura 04):

Figura 06 Tabela para cadastrar e-mail


automaticamente com o auxlio de TRIGGERS.
Definindo o TRIGGER para pegar os valores
Figura 04 TRIGGER para impor integridade
referencial ao campos que se relacionam com
outras tabelas.

inseridos na coluna cliente_email da tabela


tbl_cliente e inserir tambm na tabela
tbl_newsletter. Segue definido na Figura 07.

Como somente criamos a tabela e no inserimos


nenhum cliente e nem produto algum, qualquer
tentativa de insero na tabela tbl_compra falhar,
como mostra a figura seguinte (Figura 05):

Figura 07 Insero automtica de e-mail em


outra tabela.
Testando o TRIGGER na Figura 08:

Figura 05 Implementando restrio de


integridade referencial com TRIGGERS.
Uma outra aplicao para se trabalhar com
TRIGGERS ter uma tabela para e-mail para ser
utilizada por algum sistema de newsletter da
empresa. Podemos facilmente nesse caso,
implementar um TRIGGER para colher os e-mail do
cadastro de clientes e estes serem inseridos em

15

Concluso
Apresentamos neste artigo, os principais conceitos
de implementaes de TRIGGERS, com os
operadores OLD e NEW. No prximo artigo
mostrarei como impedir uma excluso de um dado
baseado em outras tabelas relacionadas e como
construir um log no banco de dados com um
TRIGGER disparado com a instruo UPDATE, onde
temos acesso ao antes e o depois das alteraes.
Figura 08 Os endereos de e-mails de clientes
sendo inseridos automaticamente por meio de
TRIGGERS.
Excluir um TRIGGER
Para excluir um TRIGGER, utilize a sintaxe DROP
TRIGGER trigger_name, como mostra o exemplo da
Figura 09.

No ouo comentrios a respeito do uso de Triggers e


Stored Procedures no banco de dados MySQL. Talvez por
que, quem conhea e utilize estas ferramentas, prefira
trabalhar com outros bancos mais robustos como Oracle,
SQL Server e h espao at para o PostgreSQL.
Esses dias, enquanto migrava uma aplicao que uso no
trabalho do framework Code Igniter para o Kohana, percebi
que poderia poupar cdigo se fizesse a implementao de
algumas atividades direto no banco, com o uso de Triggers,
que esto disponveis no MySQL 5.
Minha aplicao possui a entidade Tarefa, com 4 campos
de data descritos, de forma que eu consigo controlar
quando eu deveria ter iniciado a atividade, e comparar com
quando, realmente, isso foi realizado. Os campos so: data
prevista de incio; data de incio realizada; data prevista de
trmino; e data de trmino realizada.
O problema que eu tinha que muitas vezes eu precisava
replanejar as datas previstas, por um motivo qualquer,
como um atraso em uma atividade anterior, que era de
responsabilidade do cliente. Ento eu simplesmente
entrava no sistema e alterava as datas previstas, mas
precisava guardar um histrico, armazenando as datas
anteriores e o motivo deste replanejamento.

Figura 09 Excluindo um TRIGGER.


Restries em relao TRIGGERS
A implementao deste recurso atualmente no
MySQL tem vrias limitaes, a conferir as
principais:
- No se pode chamar diretamente um TRIGGER
com CALL, como se faz com um Stored Procedures;
- No permitido iniciar ou finalizar transaes
em meio TRIGGERS;
- No se pode criar um TRIGGERS para uma
tabela temporria TEMPORARY TABLE;
- TRIGGERS ainda no podem ser implementadas
com a inteno de devolver para o usurio ou para
uma aplicao mensagens de erros.

Para resolver isto via cdigo na aplicao, teria que


implementar um mtodo "after_save" em tarefas, verificar
se houve replanejamento das datas, carregar um objeto
entidade Replanejamento, preenche-lo com os dados e
salv-lo. A outra opo foi criar esta trigger no banco de
dados:
view sourceprint?
01.CREATE TRIGGER log_replanejamento AFTER UPDATE ON
tarefas
02. FOR EACH ROW
03.
BEGIN
04.
IF OLD.dt_inicio_previsto <>
NEW.dt_inicio_previsto OR OLD.dt_fim_previsto <>
NEW.dt_fim_previsto THEN
05.
INSERT INTO replanejamentos SET
06.
tarefa_id = OLD.id,
07.
dt_inicio_previsto =
OLD.dt_inicio_previsto,
08.
dt_inicio_realizado =
OLD.dt_inicio_realizado,

16
09.
dt_fim_previsto =
OLD.dt_fim_previsto,
10.
dt_fim_realizado =
OLD.dt_fim_realizado,
11.
dt_replanejamento = NOW(),
12.
observacao = OLD.observacao;
13.
END IF;
14.
END;
Pra quem no est acostumado com a sintaxe das Triggers,
uma "traduo" do comando seria: Crie a trigger
LOG_REPLANEJAMENTO aps atualizaes em TAREFAS.
Para cada linha, se a data de inicio prevista for diferente da
nova data de inicio prevista, OU se a data de fim prevista
for diferente da nova data fim prevista, insira na tabela
REPLANEJAMENTOS.

Stored procedures tambm permitem que voc tenha bibliotecas de


funes no servidor de banco de dados. Esta uma caracterstica
partilhada por linguagens de aplicaes modernas que permitem
que tal projeto internamente (por exemplo, usando classes). Com
estes recursos de linguagem aplicativo cliente benfico para o
programador mesmo fora do mbito de utilizao do banco de
dados.
MySQL segue a sintaxe SQL: 2003 para stored procedures, que
tambm usada pelo DB2 da IBM.
A implementao do MySQL de stored procedures ainda est em
andamento. Todas as sintaxes descritas aqui so suportadas e
qualquer limitao e extenso so documentados onde for
apropriado.

17.2.4. Stored Procedures, Functions, Triggers e LAST_INSERT_ID()


No primeiro artigo
Stored procedures (procedimentos e funes) so suportadas no
MySQL 5.0. A rotina armazenado um conjunto de instrues SQL
que podem ser armazenados no servidor. Uma vez que este tem
sido feito, os clientes no precisam de reenviar os comnados
indivduo, mas pode referir-se rotina armazenado.
Stored procedures exigem a proc tabela no mysql banco de
dados. Esta tabela criada durante o procedimento de instalao
do MySQL 5.0. Se voc estiver atualizando para o MySQL 5.0 a
partir de uma verso anterior, certifique de atualizar a sua tabela de
permisso para se certificar de que o proc tabela existe. Veja
Seo 4.4.9, "mysql_upgrade - Tabelas Verifique para Upgrade
MySQL" .
Rotinas armazenadas podem ser particularmente til em
determinadas situaes:

Quando vrias aplicaes clientes so escritas em


diferentes linguagens ou funcionam em diferentes
plataformas, mas precisam realizar as operaes de banco
de dados mesmo.
Quando a segurana primordial. Bancos, por exemplo,
use os procedimentos armazenados e funes para todas
as operaes comuns. Isto fornece um ambiente
consistente e seguro, e rotinas pode garantir que cada
operao devidamente registrada. Em tal configurao,
aplicaes e usurios no teriam

comp=4442&hl, foram apresentados os conceitos,


vantagens, sintaxe bsica e um exemplo de aplicao das
stored procedures. Nesse prximo ser apresentado mais
conceitos e aplicaes alm de exemplos na linguagem
vb.net. As stored procedures permitem que processos
(condicionais, repeties , funes e etc) antes feitos
dentro do cdigo fonte do programa sejam agora todos
incorporados dentro dos seus procedimentos armazenados
no banco de dados, possibilitando assim cdigos fontes de
programas cada vez menores e mais leves no lado do
cliente, mas em compensao do outro lado o servidor ser
mais exigido em termos de processamento do SGBD .

Estrutura IF|ELSE

Sintaxe:

IF <condio> THEN

http://www.devmedia.com.br/articles/viewcomp.asp?

acesso s tabelas do banco de dados diretamente, mas s


pode executar rotinas especficas armazenadas.

Stored procedures podem fornecer um melhor desempenho, pois


menos informao precisa ser enviada entre o servidor eo cliente.
A desvantagem que isto aumenta a carga sobre o servidor de
banco de dados porque a maior parte do trabalho feito no lado do
servidor e menos feito no cliente (aplicao). Considere isto
existem muitas mquinas clientes (como servidores Web) so
atendidos por apenas um ou poucos servidores de banco de dados.

<comandos sql caso verdadeiro>


ELSE
<comandos sql caso falso>
END IF

17
Para exemplificar os conceitos acima, considere o seguinte

Humberto Melo

Ayrton Senna

conforme desejado por ele:

Xuxa

Resoluo:

Agora o proximo passo o foco do artigo a criao da

problema:
Tem-se um cadastro de clientes (cdigo, nome e sexo) e
precisa-se de uma interface que liste na tela do usurio
o(s) cliente(s) de sexo feminino, masculino ou ambos,

procedure utilizando a estrutura condicional:


Passo 4) Criar uma procedure que liste os clientes
masculino ou feminino ou ambos e demonstre o resultado

Nome Tabela: Tbl_clientes

num data grid usando VB.NET, considerando a tabela


Atributos: Cdigo, Nome, Sexo.

clientes acima.

Passo 1) Criando tabela Tbl_clientes:

Passo 4.1) Criar a procedure: (OBS: Usar o query


browser para escrever a procedure).

create table tbl_clientes (


Procedure : sp_lista_clientes
codigo int not null primary key auto_increment,
delimiter $$

nome varchar(40) not null,

create procedure sp_lista_clientes(in opcao integer)

sexo char(1) not null)

begin
if opcao = 0 then
Passo 2) Inserindo registros:
select * from tbl_clientes where sexo = F;
else
insert into tbl_clientes(nome,sexo) values(Humberto,M)

if opcao = 1 then

insert into tbl_clientes(nome,sexo) values(Ayrton Sena,M)


insert into tbl_clientes(nome,sexo) values(Xuxa,F)
Passo 3) Verificando registros:

select * from tbl_clientes where sexo = M;


else
select * from tbl_clientes;
end if;

Select * from tbl_clientes

end if;
end $$

codigo

Nome

Sexo delimiter ;

18
Concluses e Resultados:

A procedure acima utiliza os conceitos de da estrutura


IF/ELSE, o resultado uma lista dos clientes de acordo com
a opo desejada.
Chamando a procedure:

Lista sexo Feminino: CALL sp_lista_clientes(0);


Lista sexo Masculino: CALL sp_lista_clientes(1);
Lista todos: CALL sp_lista_clientes(2);

OBS: na ultima chamada CALL sp_lista_clientes(2), foi


escolhido a opo 2, sendo que poder ser escolhida
qualquer opo desde que seja diferente de 0 ou 1.

4.2) Interface no VB.net


Abra o visual studio 2003 , inicie um projeto windows
application com a seguinte interface:
OBS:
nome dos objetos: data grid = dgclientes
radiobutton1 = rbdtodos
radiobutton2 = rbdpersonalizada
comboBox1 = cmbsexo (adicionar os items Masculino e
feminino)
Variavel global: dim flag as integer variavel que servira de
parametro para procedure

nos eventos checked dp radiobutton1 tratar a seguinte


situacao:

19
Private Sub RadioButton1_CheckedChanged(ByVal sender

Abaixo tem-se o evento do objeto button (pesquisar):

As System.Object, ByVal e As System.EventArgs) Handles


rbdtodos.CheckedChanged

If cmbsexo.Text = "Clique aqui para escolher" And


rbdpersonalizada.Checked Then

flag = 2
MessageBox.Show("Opo invalida,favor escolher o sexo
cmbsexo.Enabled = False

Feminino ou masculino", "Observaco",


MessageBoxButtons.OK, MessageBoxIcon.Information)

End Sub
Else
O evento acima quando "acionado" atribui a variavel flag o
valor 2, que significa na procedure todos os sexos conforme

##### DECLARAO DE VARIAVEIS

visto anteriormente na criao da procedure. Alm disso o

#######################

cmbsexo e desabilitado pois nao faz sentido o usuario


escolher o sexo se o mesmo que listar ambos.

Dim conexao As MySqlConnection Definindo variavel


conexao com o BD

Private Sub RadioButton2_CheckedChanged(ByVal sender


As System.Object, ByVal e As System.EventArgs) Handles

Dim Da As MySqlDataAdapter

rbdpersonalizada.CheckedChanged
Dim clientes As DataTable
cmbsexo.Enabled = True
Dim tableStyle As New DataGridTableStyle
End Sub
Dim colunas As New DataGridTextBoxColumn coluna do
O evento acima quando "acionado" habilita o comboBox

grid

cmbsexo para que o usuario possa escolher o sexo.


Dim cmdsql As MySqlCommand variavel que recebera nome
Private Sub ComboBox1_SelectedIndexChanged(ByVal

procedure

sender As System.Object, ByVal e As System.EventArgs)


Handles cmbsexo.SelectedIndexChanged

Dim parametro As New MySqlParameter varivel parametro


procedure

If cmbsexo.SelectedIndex = 0 Then
########## FIM DA DECLARACAO DE VARIAVEIS
flag = 1
conexao = New MySqlConnection("server=localhost;user
Else

id=root;password=1234;database=testes")

flag = 0

parametro.ParameterName = "opcao" declaracao do


parametro da procedure

End If
parametro.Value = flag
End Sub
O evento acima quando "acionado"( acionado quando
escolhido a opcao no combo), atribui a variavel flag o valor

artibuicao do valor da flag ao

parametro
cmdsql = New MySqlCommand("sp_lista_clientes",
conexao)

1, que significa na procedure sexo masculino e 0 caso seja


feminino ,conforme visto anteriormente na criao da

cmdsql.CommandType = CommandType.StoredProcedure

procedure.

definindo o tipo de comando sql


cmdsql.Parameters.Add(parametro)

adiciona parametro

20
Da = New MySqlDataAdapter(cmdsql)

chama procedure

Nota-se que com as stored procedures pode-se fazer


aplicaes bastantes interessantes usando estruturas IF|

clientes = New DataTable

ELSE e em breve ser demonstrada outras estruturas por


exemplo: WHILE. Ento pessoal mo obra e at o

Da.Fill(clientes)
tableStyle.MappingName = clientes.TableName.ToString

prximo artigo aqui com mais coisas interessantes sobre


stored procedures.

colunas.MappingName = "nome"
Criando Stored Procedures no MySQL
colunas.HeaderText = "nome"
A maioria das pessoas no sabe a vantagem de utilizar Stored
colunas.Width = 150
tableStyle.GridColumnStyles.Add(colunas)

Procedures, ou simplesmente no conhecem est funcionalida


de a sua simplicidade de usar. Nesta matria eu mostraria com
criar Procedures bsicas para simplificar tarefas repetivas de
acesso a banco.

colunas = New DataGridTextBoxColumn

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

tableStyle.MappingName = clientes.TableName.ToString

A maioria das pessoas no utiliza todos os recursos disponveis para os


SGBDs, tais como Stored Procedures e Triggers.

colunas.MappingName = "codigo"
Primeiramente vamos a algumas questes.
colunas.HeaderText = "codigo"
O que uma Stored Procedure?
colunas.Width = 80
tableStyle.GridColumnStyles.Add(colunas)
dgclientes.TableStyles.Add(tableStyle)

uma colao de comandos SQL, que encapsula uma srie de tarefas


repetitivas, relativas ao acesso a banco, aceita parmetros de entrada e
retorna um valor de status ou conjunto de registros.
Por que usar um Stored Procedure?

dgclientes.DataSource = clientes
As Stored Procedures ajudam a reduzir o trfego na rede, a melhorar o
End If

desempenho de consultas, a criar mecanismos de segurana e

Primeiro testado caso a pesquisa seja personalizada se


algum sexo foi escolhido, senao ele apresenta uma
mengagem de erro ao usuario. A declaracao da procedure
esta comentada no codigo acima. No final apenas a
configuracao das colunas do grid.
Concluses:

Atraves de stored procedure pode-se tratar os


eventos condicionais, o que ajuda os dbas no
controle de processos no banco de dados, inclusive
para validar dados;

Uma desvantagem seria mais processamento do


lado do servidor.

simplificar o cdigo da aplicao, j que no haver a necessidade de


manter consultas SQL de vrias linhas misturadas a toda lgica da sua
aplicao.
Ento

vamos

ao

banco

exemplo:

21
um banco bem simples, mas s para vermos na prtica o

de entrada, OUT, apenas de sada e INOUT, entrada e sada. Os tipos

funcionamento das procedures.Vamos a primeira, listar pases:

de dados dos parmetros so os mesmo tipos de dados do SGBDs


(

DELIMITER $$

INT,

VARCHAR(45),

TEXT,

BLOB...)

Entre os comandos BEGIN e END que sero colocados os comandos


executados

pela

procedures.

DROP PROCEDURE IF EXISTS `listar_paises` $$

Primeiramente eu verifico se foi passado o parmetro id para a

CREATE PROCEDURE `listar_paises`(IN _id INT)

procedure.

BEGIN
IF(_id IS NULL) THEN
IF(_id IS NULL) THEN
SELECT * FROM pais;
ELSE
SELECT * FROM pais where id_pais = _id;
END IF;
END $$
DELIMITER ;

Caso tenha sido passado eu busco um pas com aquele id, em caso
contrrio

sero

retornados

todos

os

registros

da

tabela.

Chamando a procedure.
call listar_paises( null );
Ir trazer todos os registros da tabela

Vamos a explicao.
call listar_paises( 1 );
DELIMITER $$ Serve para marcar onde comea e onde termina a

Ir

procedure, neste caso eu escolhi $$

Procedures so to simples quanto parecem. Coloquei em anexo os

DROP PROCEDURE IF EXISTS `listar_paises` - nesta linha eu informo


ao SGBD que se a procedure j existir eu a estarei sobrescrevendo.
CREATE PROCEDURE - ir cria a procedure, note que h um
parmetros para esta procedures. Os parmetros podem ser IN, apenas

trazer

somente

registro

do

pas

com

ID

1;

cdigos fontes do banco com mais algumas procedures caso voc


queira dar uma olhada. Na prxima matria eu explicarei como incluir,
atualizar e apagar registro do banco usado procedures.
Leia mais no Oficina da Net: Criando Stored Procedures no MySQL

Potrebbero piacerti anche