Voltamos a falar dos procedimentos Armazenados ( Stored Procedures ou SP , também consultas armazenadas ou QueryDefs ), pois tem muita gente que ainda não sabe usar ou não conhece o poder das SP. Por isso vou rever alguns conceitos básicos... Não se inquiete...
Quando você cria o seu projeto no Visual Basic e resolve usar SQL para fazer o tratamento dos seus dados , com certeza , fez um escolha certa. Agora este artigo vai lhe mostrar que você pode ir além aperfeiçoando ainda mais o seu código com reflexos na produtividade , manutenção e escalonabilidade do seu sistema. Mas aonde eu estou querendo chegar ?
Sendo o mais direto possível eu já vou lhe dizer que os Procedimentos Armazenados são mais eficientes que as instruções SQL que você embute em seu código. Vamos começar com algumas comparações para você ter uma idéia:
Procedimentos Armazenados | Instruçoes SQL ( Consultas SQL ) |
São mais rápidos pois são compilados previamente pelo mecanismo do banco de dados | São mais lentos pois precisam ser interpretados em tempo de execução |
Fácil manutenção , pois qualquer alteração , apenas vai requerer que você altera o procedimento no banco de dados e o redistribua | Manutenção mais complexa, pois você vai ter que abrir o seu código , fazer as alterações , recompilar o seu projeto e redistribuí-lo novamente. |
Relativamente Flexível com a utilização de parâmetros. | Muito flexível com a utilização de consultas parametrizadas e variáveis. |
Leitura fácil devido a sua estrutura enxuta. | Mais difícil de ler devido as concatenações , variáveis e outros caracteres. |
Como os Procedimentos Armazenados residem no banco de dados , a manutenção fica centralizada , e você não tem que abrir o código do seu projeto , bastando apenas fazer as alterações e distribuir o banco de dados.
Criando um Procedimento Armazenado com o Microsoft Access 2000
Para quem esta começando pode parecer estranho ter uma instrução armazenada no banco de dados , mas é justamente ai que reside a grande vantagem dos Procedimentos Armazenados. Se você conhece bem a sintaxe SQL pode criar os seus procedimentos armazenados para realizar as tarefas usuais de manutenção dos seus dados : Incluir , alterar, excluir e consultar registros.
A maneira mais fácil de criar um procedimento armazenado é usar o Microsoft Access e fazer uso dos recursos visuais e gráficos que ele nos oferece. Como exemplo vamos criar um procedimento armazenado usando o Access 2000.
Vamos usar o banco de dados Biblio.mdb e criar um procedimento para exibir os dados da tabela Publishers. Nosso procedimento vai usar um critério para exibir os dados ; o critério será o campo state. Vamos dar um nome ao nosso procedimento , que tal ConsultaEditoresEstado.; vamos exibir os campos Name e Company Name Abaixo temos a estrutura da tabela Publishers:
A tabela Publishers : Vamos exibir os campos Name e Company Name e selecionar os registros pelo campo State. |
1-) Inicie o Microsoft Access 2000 e abra o banco de dados Biblio.mdb ; Selecione o menu Consulta e a seguir a opção : Criar consulta no modo estrutura
O banco de dados Biblio.mdb : Exibindo as consultas ; note que ja temos uma consulta armazenada chamada All Titles |
2-) Na janela : Mostrar Tabela , selecione a tabela Publishers e clique no botão adicionar . Feito isto clique no botão Fechar pois vamos trabalhar somente com a tabela Publishers.
A janela onde vamos incluir as tabelas que iremos usar para construir nosso Procedimento Armazenado |
3-) Na janela a seguir você verá a tabela Publishers com os seus campos ; Clique duas vezes no campo Name e Company Name (Os campos que queremos incluir).
Os campos selecionados sendo exibidos na ordem em que serão extraidos. |
Perceba que os campos aparecem na ordem que foram inseridos.
4-) Falta informar o critério ( este critério será o nosso parâmetro) . Selecione o campo State .
5-) Agora no menu principal selecione a opção Consulta|Parâmetros e informe o nome do parâmetro(comece com a letra p) e o tipo de dados. Utilizamos o nome pestado. Para completar , na linha Critério informe sob a coluna State o critério : =[pestado]. (Ver abaixo)
6-) Selecione a Exibir no menu e a seguir a opção Modo SQL e você verá a consulta com o parâmetro exibida no formato SQL:
7-) Se você executar a consulta agora , menu Consulta|Excecutar ira receber uma janela solicitando o parâmetro para seleção . Informe MA e tecle Enter você deverá obter o seguinte:
8-) Agora é só dar um nome a sua consulta e salvá-la. Antes disto vamos fazer uns ajustes...
Fiz tudo isto somente para mostrar que você pode armazenar uma consulta no seu banco de dados Access. Mas o que queremos é usar esta consulta no Visual Basic , então vamos fazer alguns ajustes. Primeiro eu tenho que ter em mente qual a consulta que quero criar(quais registros vou exibir, qual tabela usar, etc...) ; depois tenho que definir quais parâmetros eu vou usar para selecionar os registros.Para este nosso caso no visual Basic usando a sintaxe SQL teriamos :
SELECT Name , [Company Name] From Publishers Where State = pestado
Então esta seria a consulta que iríamos armazenar no banco de dados. Vamos pois salvá-la com o nome indicado : ConsultaEditoresEstado.
Como usar esta consulta ? Vamos mostrar como usá-la na DAO e depois com ADO.
I-) Usando o Procedimento Armazenado ( Consulta Parametrizada) na DAO. (Again)
- Inicie um novo projeto no Visual Basic e insira no formulário padrão os controles: listbox , command button , text box e label. Conforme Layout a seguir:
2-) Insira o seguint código na seção General Declarations
Private db As Database Private qd As QueryDef Private rs As Recordset |
3-) Agora insira o seguinte código no evento Load do formulário: Estamos definindo a consulta - ConsultaEditoresEstado - já criada e armazenada no banco de dados como a consulta a ser utilizada.
Private Sub Form_Load() Set db = OpenDatabase("c:\teste\biblio_2001.mdb") Set qd = db.QueryDefs("ConsultaEditoresEstado") End Sub |
4-) Insira o código a seguir no evento Click do botão de comando: Invocamos a procedure ExibeEditores.
Private Sub Command1_Click() If Text1.Text <> "" Then ExibeEditores End If End Sub |
4-) A seguir insira o seguinte código na função ExibeEditores:
Private Sub ExibeEditores() qd.Parameters("pestado").Value = Text1.Text Set rs = qd.OpenRecordset If rs.RecordCount = 0 Then MsgBox "Não há dados para o criterio ! " Exit Sub End If While Not rs.EOF List1.AddItem rs("name") rs.MoveNext Wend End Sub |
- Passamos o valor informado na caixa de texto Text1.text como sendo o parâmetro para nossa consulta armazenada e a seguir geramos um recordset com base nesta consulta usando o parâmetro informado. Se houver dados a serem retornados eles serão exibidos em um listbox.
II-) Usando Procedimentos Armazenados ( Consultas Parametrizadas) com ADO.
Tudo bem , você não quer mais usar DAO ( dependendo da ocasião pode ser uma péssima atitude ). Então vamos mostrar como usar o nosso Procedimento Armazenado usando ADO. Antes um pouco de teoria:
Um objeto Parameter representa um parâmetro ou argumento associado a um objeto Command que esta baseado em uma consulta parametrizada ou procedimento armazenado. Abaixo temos uma representação do objeto Command , a coleção Parameters e o objeto Parameter
Sabendo o nome dos parâmetros associados aos procedimentos armazenados que desejamos chamar podemos usar o método CreateParameter para criar objetos Parameter , e , usando o método Append incluir estes parâmetros na coleção Parameters. Com isto podemos definir e retornar valores sem ter que usar o método Refresh na coleção Parameters para retornar o valor do parâmetro a partir do provedor.
O método CreateParameter cria um objeto Parameter com as propriedades especificas. Sua sintaxe é a seguinte:
Set parameter = command.CreateParameter (Name, Type, Direction, Size, Value)
Onde:
Constante | Descrição |
adBoolean | Um valor Boolean. (DBTYPE_BOOL). |
adChar | Um Valor String (DBTYPE_STR). |
adDate | Um Valor do tipo Data (DBTYPE_DATE). |
adDouble | Um valor do tipo double.(DBTYPE_R8). |
adEmpty | Um valor não definido.(DBTYPE_EMPTY). |
Constante | Descrição |
adParamUnknown | Indica que a direção é desconhecida. |
adParamInput | Valor padrão. Indica um parâmetro de entrada. |
adParamOutput | Indica um parâmetro de saida |
adParamInputOutput | Indica um parâmetro de entrada e de saida. |
adParamReturnValue | Indica um valor de retorno. |
Após criar o objeto Parameter você tem que incluir o parâmetro usando o método Append. A sintaxe é a seguinte:
collection.Append object
Criando os procedimentos armazenados
Vamos mostrar como usar os procedimentos armazenados com ADO . Para isto vamos criar uma tabela chamada Clientes no banco de dados Biblio_2001.mdb ( este é o banco de dados Biblio.mdb renomeado ).
1-) Inicie o Access e abra o banco de dados Biblio.mdb ( no meu caso Biblio_2001.mdb )
2-) Selecione o objeto Tabela e a opção - Criar tabela no modo Estrutura.
3-) Crie a tabela - Clientes - com a estrutura abaixo:
4-) Vamos agora criar três procedimentos armazenados e salvá-los no banco de dados Biblio.mdb.
a-) Criando um procedimento armazenado para INCLUIR registros na tabela Clientes chamado - Incluir_Dados
INSERT INTO CLIENTES ( CODIGO, NOME) VALUES ([@codigo], [@nome]); |
Se você executar esta consulta no Access irá obter duas janelas solicitando o codigo e nome para incluir no banco de dados.
Salve este procedimento com o nome de : Incluir_Dados.
b-) Criando um procedimento armazenado para EXCLUIR registros na tabela Clientes chamado - Excluir_Dados
Aqui o procedimento é idêntico ao item anterior , somente vamos alterar o tipo de consulta a criar ; no menu Consulta , selecione Consulta Exclusão e defina a consulta conforme abaixo:
No menu Exibir | Modo SQL você terá:
DELETE Clientes.Codigo, Clientes.Nome
FROM Clientes
WHERE (((Clientes.Codigo)=[@Codigo]));
Salve este procedimento com o nome - Excluir_Dados
c-) Criando um procedimento armazenado para ATUALIZAR registros na tabela Clientes chamado - Atualizar_Dados
Da mesma forma repita os passos anteriores e no menu Consulta selecione a opção - Consulta Atualização . E defina a consulta conforme abaixo:
No menu Exibir | Modo SQL você verá:
UPDATE Clientes SET Clientes.Nome = [@nome]
WHERE (((Clientes.Nome)=[@codigo]));
Salve o procedimento com o nome de Atualiza_Dados
d-) Criando um procedimento armazenado para SELECIONAR registros na tabela Clientes chamado - Seleciona_Dados
Novamente como no item anterior repita os passos e no menu Consulta selecione a opção - Consulta Seleção . Defina a consulta como abaixo:
No menu Exibir | Modo SQL teremos:
SELECT Clientes.Codigo, Clientes.Nome
FROM Clientes
WHERE (((Clientes.Codigo)=[@codigo]));
Salve o procedimento com o nome de Seleciona_Dados. Ao final no banco de dados vamos ter as 4 consultas armazenadas indicas assim:
Agora que já temos os procedimentos armazenados basta usá-los no VB . Vamos la´...
- Inicie um novo projeto no VB e no formulário padrão insira duas caixas de textos e sete botões de comando como no layout abaixo:
Obs: Este projeto é apenas um exemplo em que focamos
a utilização das Stored Procedures via
código com ADO. Não me preocupei com a interface nem com a critica aos dados. Se você pretender usar o exemplo , deverá ajustar o código para funcionar com o tratamento de erros e com a critica aos dados. |
Na seção General Declarations inclua o código:
Private con As New Connection Private cmd As New Command Private rst As New Recordset Private codigo As String |
- O código do evento Load do formulário : Ajuste o nome e a localização do banco de dados para o seu caso particular . !
Private Sub Form_Load() 'abre a conexao com o banco de dados con.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\teste\biblio_2001.mdb" rst.Open "Select codigo, nome from Clientes", con, adOpenKeyset, adLockPessimistic exibe_registros End Sub |
- O código do botão Incluir , onde vamos usar o procedimento armazenado - Inclui_Dados. Ao clicar neste botão , limpamos as caixas de texto e habilitamos o botão Gravar que invocara a rotina Inclui_regs.
Private Sub Command1_Click(Index As Integer) Select Case Index Case 0 'incluir limpa_ctrls txtnome.SetFocus Command2.Visible = True Case 1 'excluir exclui_regs Case 2 'atualizar atualiza_regs Case 3 'selecionar If Command1(3).Caption = "&Filtro" Then codigo = InputBox("Informe o Codigo do Cliente", "Atualizar", 1) If codigo <> "" Then codigo = Val(codigo) seleciona_regs Command1(3).Caption = "&Todos" Else Exit Sub End If ElseIf Command1(3).Caption = "&Todos" Then exibe_todos Command1(3).Caption = "&Filtro" End If End Select End Sub |
- Abaixo temos o código do procedure Inclui_regs. Usamos aqui o procedimento armazenado Inclui_Dados que é invocado quando o usuário clica no botão Gravar ; criamos o parâmetro usando o conteúdo da caixa de texto para inserir o dado na tabela. Como o campo codigo é autonomeração o sistema irá automaticamente incrementar o valor para este campo.
Private Sub inclui_regs() Set cmd = New Command Set par = New Parameter With cmd Set .ActiveConnection = con .CommandText = "Inclui_Dados" .CommandType = adCmdStoredProc Set par = .CreateParameter("@nome", adVarChar, , 50, txtnome) .Parameters.Append par .Execute End With rst.MoveLast exibe_registros End Sub |
Private Sub Command2_Click() inclui_regs Command2.Visible = False End Sub |
Código da procedure Inclui_regs | Código do botão de comando Gravar |
- Abaixo o código da procedure Exclui_regs : Ela usa o procedimento Armazenado Excluir_Dados , usando como parâmetro o código do cliente informado na caixa de texto txtcodigo.
Private Sub exclui_regs() Set cmd = New Command Set par = New Parameter With cmd Set .ActiveConnection = con .CommandText = "Excluir_Dados" .CommandType = adCmdStoredProc Set par = .CreateParameter("@codigo", adInteger, , , txtcodigo) .Parameters.Append par .Execute End With rst.MovePrevious exibe_registros End Sub |
- O código da procedure Atualiza_regs , a seguir , usa o procedimento armazenado Atualiza_Dados e os parâmetros : txtnome e txtcodigo para atualizar os dados de um registro.
Private Sub atualiza_regs() Set cmd = New Command Set par = New Parameter With cmd Set .ActiveConnection = con .CommandText = "Atualiza_Dados" .CommandType = adCmdStoredProc Set par = .CreateParameter("@nome", adVarChar, , 50, txtnome) .Parameters.Append par Set par = .CreateParameter("@codigo", adInteger, , 5, txtcodigo) .Parameters.Append par .Execute End With exibe_registros End Sub |
- O código associado ao evento click do botão - Filtro - é o seguinte:
If Command1(3).Caption = "&Filtro" Then codigo = InputBox("Informe o Codigo do Cliente", "Atualizar", 1) If codigo <> "" Then codigo = Val(codigo) seleciona_regs Command1(3).Caption = "&Todos" Else Exit Sub End If ElseIf Command1(3).Caption = "&Todos" Then exibe_todos Command1(3).Caption = "&Filtro" End If |
Ele solicita um número relativo ao código do cliente para Filtrar os dados com base neste valor. Se um valor válido for informado invocamos a procecure Selecina_regs , cujo código é:
Private Sub seleciona_regs() Set cmd = New Command Set par = New Parameter With cmd Set .ActiveConnection = con .CommandText = "Seleciona_Dados" .CommandType = adCmdStoredProc Set par = .CreateParameter("@codigo", adInteger, , , codigo) .Parameters.Append par Set rst = .Execute End With exibe_registros End Sub |
O procedimento armazenado Seleciona_Dados é utilizado com o parâmetro codigo ( informado no evento anterior ). Aqui temos uma Consulta Seleção com um parâmetro.
Após Filtrar os dados , lembre-se que o recordset gerado terá apenas um registro. Para voltar a exibir todos os registros clique no botão Todos ( o mesmo botão - Filtro com a propriedade caption alterada.) que o usa o seguinte código para gerar um recordset com todos os registros do arquivo:
Private Sub exibe_todos() Set cmd = New Command With cmd Set .ActiveConnection = con .CommandText = "Exibe_Todos" .CommandType = adCmdStoredProc Set rst = cmd.Execute End With exibe_registros End Sub |
Aqui usamos um procedimento armazenado - Exibe_Todos - sem parâmetros; apenas uma Consulta Seleção.
Para encerrar o projeto o código que exibe os registros nas caixas de texto e o código para navegar pelos registros:
Private Sub exibe_registros() If rst.BOF Or rst.EOF Then MsgBox "Chegamos ao Inicio/Fim do arquivo !" If rst.BOF And rst.EOF Then MsgBox "Não há dados no arquivo ! " Exit Sub End If If rst.BOF Then rst.MoveFirst If rst.EOF Then rst.MoveLast Else txtcodigo = rst("codigo") txtnome = rst("nome") End If End Sub |
Private Sub Command3_Click(Index As Integer) Select Case Index Case 0 rst.MovePrevious Case 1 rst.MoveNext End Select exibe_registros End Sub |
Código para exibir os registros nas caixas de texto | Código para navegar pelos registros |
Ufa ! acho que agora terminei ...
CopyRight-2001 - José Carlos Macoratti