Trabalhando com Recordsets - Alterando e Retornando dados.
O objeto Recordset esta presente tanto na DAO como na ADO. Lembre-se que um Recordset representa um conjunto de registros de uma tabela ou o conjunto de registros resultante de uma consulta SQL.
O objeto Recordset contém a coleção Fields que contém o objeto Field que representa uma coluna de dados de um Recordset.
Usando a ADO podemos abrir um Recordset das seguintes formas:
Não podemos abrir um objeto Recordset da ADO diretamente de um objeto Table ou Procedure ou View.
Os Recordsets abertos via método Execute são sempre forward-only e somente leitura. Se você precisar criar recordsets atualizáveis deve usar o método OPEN do objeto Recordset da ADO. A sintaxe é a seguinte:
recordset.Open Source, ActiveConnection, CursorType, LockType, Options
Source - É Opcional e indica o um comando para o nome da variável objeto, uma instrução SQL , o nome de uma tabela ou uma stored procedure
ActiveConnection - É Opcional e indica um nome da variável objeto Connection , ou uma string contendo parâmetros para a ConnectionString.
CursorType - É Opcional. Determina o tipo de cursor que o provedor irá usar quando abrir o Recordset. Pode ser dos seguintes tipos:
adOpenForwardOnly | (Padrão) Abre um cursor do tipo forward-only. |
adOpenKeyset | Abre um cursor do tipo keyset. (Não permite visualizar registros excluidos por outro usuário) |
adOpenDynamic | Abre um cursor do tipo dynamic.(Exclusão,Inclusão e alterações feitas são visíveis) |
adOpenStatic | Abre um cursor do tipo static.(Cópia estática de um conjunto de registros) |
Os parâmetros CursorType, LockType e Options do método Open determinam o tipo de Recordset que é retornado.
Vejamos na tabela abaixo como os parâmetros do método OPEN do objeto Recordset podem ser mapeados para as propriedades da ADO.
Tipo de Recordset DAO | Propriedades ou parâmetros do Recordset ADO |
dbOpenDynaset | CursorType=adOpenKeyset |
dbOpenSnapshot | CursorType=adOpenStatic |
dbOpenForwardOnly | CursorType=adOpenForwardOnly |
dbOpenTable | CursorType=adOpenKeyset, Options=adCmdTableDirect |
Opção de valores para o Recordset DAO | Propriedades do Recordset ADO |
dbAppendOnly | Properties("Append-Only Rowset") |
dbSQLPassThrough | Properties("Jet OLEDB:ODBC Pass-Through Statement") |
dbSeeChanges | Sem equivalentes |
dbDenyWrite | Sem equivalentes |
dbDenyRead | Sem equivalentes |
dbInconsistent | Properties("Jet OLEDB:Inconsistent") = True |
dbConsistent | Properties("Jet OLEDB:Inconsistent") = False |
Tipos de bloqueios(LockType) do Recordset DAO | Tipos de bloqueios(LockType) do Recordset ADO |
dbReadOnly | adLockReadOnly |
dbPessimistic | adLockPessimistic |
dbOptimistic | adLockOptimistic |
O objeto Recordset da ADO possui a propriedade CursorLocation que pode ter dois valores: adUseServer e adUseClient. O padrão assumido é adUseServer , com ele a performance é bem melhor , para base de dados locais. Para acesso a base de dados cliente-Servidor , tipo SQL-Server, o valor adUseClient apresenta melhor resultado.
De uma forma geral usamos adUserServer, devemos ter em mente que com isto não poderemos usar os métodos Find e Sort no Recordset.
Abrindo um Recordset somente-leitura e forwardOnly.
Abrindo a base de dados NWIND.MDB e a tabela Clientes , mostrando todas a informações dos clientes cuja cidade for igual a SP .
DAO
Dim
db As DAO.Database Dim rst As DAO.Recordset Dim fld As DAO.Field 'Abre a base de dados Set db = DBEngine.OpenDatabase("C:\nwind.mdb") 'Abre o Recordset Set rst = db.OpenRecordset("Select * from Clientes where Cidade" & _ " = 'SP'", dbOpenForwardOnly, dbReadOnly) 'Imprime os valores dos campos para o primeiro registro For Each fld In rst.Fields Debug.Print fld.Value & ";"; Next 'Fecha o Recordset rst.Close |
ADO
Dim
cnn As New ADODB.Connection Dim rst As New ADODB.Recordset Dim fld As ADODB.Field 'Abre uma conexão cnn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=C:\nwind.mdb;" 'Abre o Recordse somente-leitura rst.Open "Select * from Clientes where Cidade = 'SP'", cnn, _ adOpenForwardOnly, adLockReadOnly 'Imprime os valores dos campos para o primeiro registro For Each fld In rst.Fields Debug.Print fld.Value & ";"; Next 'Fecha o Recordset rst.Close |
Movendo-se através de um Recordset
Em um recordset o ponteiro do registro pode estar nas seguintes posições: BOF - Antes do primeiro registro, EOF - depois do último registro ou em qualquer posição dentro do Recordsert.
Os métodos de movimentação de um registro para o outro , tanto em DAO como na ADO , são : Move, MoveFirst, MoveLast, MoveNext, e MovePrevious. Vejamos abaixo exemplo para o método Movenext.
DAO
Dim
db As DAO.Database Dim rst As DAO.Recordset Dim fld As DAO.Field 'Abre a base de dados Set db = DBEngine.OpenDatabase("C:\nwind.mdb") 'Abre o Recordset Set rst = db.OpenRecordset("Select * from Customers where Region" & _ " = 'WA'", dbOpenForwardOnly, dbReadOnly) 'Imprime os valores para o campo do primeiro registro na janela de depuração While Not rst.EOF For Each fld In rst.Fields Debug.Print fld.Value & ";"; Next Debug.Print rst.MoveNext 'Move-se para o próximo registro do recordset Wend 'Fecha o recordset rst.Close |
ADO
Dim
cnn As New ADODB.Connection Dim rst As New ADODB.Recordset Dim fld As ADODB.Field 'Abre uma conexão cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;" 'Abre um Recordset do tipo forward-only rst.Open "Select * from Customers where Region = 'WA'", cnn, _ adOpenForwardOnly, adLockReadOnly 'Imprime os valores do primeiro registro na janela de depuração While Not rst.EOF For Each fld In rst.Fields Debug.Print fld.Value & ";"; Next Debug.Print rst.MoveNext 'Move-se para o próximo registro do recordset Wend 'Fecha o recordset rst.Close |
Podemos reescrever o código em ADO usando o parâmetro ActiveConnection do método Open do objeto Recordset especificando uma string connection ao invés de primeiro abrir o objeto connection. O código é:
rst.Open
"Select * from Customers where Region = 'WA'",
_ "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;", _ adOpenForwardOnly, adLockReadOnly |
Neste caso o objeto connection é criado implicitamente.
Determinando a posição atual do registro
A propriedade AbsolutePosition permite determinar o número atual do registro tanto na DAO como na ADO.Vejamos:
DAO
Dim
db As DAO.Database Dim rst As DAO.Recordset 'Abre a base de dados Set db = DBEngine.OpenDatabase("C:\nwind.mdb") 'Abre o Recordset Set rst = db.OpenRecordset("Select * from Customers", dbOpenDynaset) 'Imprime a posição do registro Debug.Print rst.AbsolutePosition 'Move-se para outro registro rst.MoveLast 'Imprime a posição do registro Debug.Print rst.AbsolutePosition 'Fecha o recordset rst.Close |
ADO
Dim
cnn As New ADODB.Connection Dim rst As New ADODB.Recordset 'Abre a conexão cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;" 'Abre o Recordset rst.CursorLocation = adUseClient rst.Open "Select * From Customers", cnn, adOpenKeyset, _ adLockOptimistic, adCmdText 'Mostra a posição do registro Debug.Print rst.AbsolutePosition 'move-se para o ultimo registro rst.MoveLast 'mostra a posicao do registro Debug.Print rst.AbsolutePosition 'fecha o recordset rst.Close |
A propriedade AbsolutePosition embora seja usada da mesma maneira em DAO e ADO retorna valores diferentes:
DAO -> A propriedade retorna o valor 0 (zero) para o primeiro registro
DAO -> A propriedade retorna o valor 1 (hum) para o primeiro registro
Observe que usamos a propriedade CursorLocation como adUseClient, se tivessemos usado o valor adUseServer a ADO iria retornar (-1)(desconhecido) para o primeiro registro do recordset.
A propriedade PercentPosition (retorna um percentual representando a posição aproximada do registro atual dentro do recordset) da DAO não esta presente na ADO. Usando o valor adUseClient para CursorLocation podemos fazer um cálculo equivalente usando a propriedade RecordCount. (Ex: (posição atual/total de registros) * 100 )
Encontrando registros em um recordset
Find e Seek , estes são os dois mecanismos usados para encontrar um registro em um recordset , tanto na DAO como na ADO. Seek é mais rápido , mas soment pode ser usado em objetos Recordsets que suportam índices.
Usando o método Find
DAO
Dim db As DAO.Database Dim rst As DAO.Recordset 'Abrindo a base de dados Set db = DBEngine.OpenDatabase("C:\nwind.mdb") 'Abrindo o Recordset Set rst = db.OpenRecordset("Customers", dbOpenDynaset) 'Procurando o primeiro cliente cujo pais seja 'USA' rst.FindFirst "Country = 'USA'" 'Agora imprimimos os codigos p/os clientes cujo país encontrado foi USA While Not rst.NoMatch Debug.Print rst.Fields("CustomerId").Value rst.FindNext "Country = 'USA'" Wend 'Fechando o Recorset rst.Close |
ADO
Dim cnn As New ADODB.Connection Dim rst As New ADODB.Recordset 'Criando uma instância do objeto Connection cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;" 'Abrindo o Recordset rst.Open "Customers", cnn, adOpenKeyset, adLockOptimistic 'Procurando o primeiro cliente cujo pais seja 'USA' rst.Find "Country='USA'" 'Agora imprimimos os codigos p/os clientes cujo país encontrado é USA While Not rst.EOF Debug.Print rst.Fields("CustomerId").Value rst.Find "Country='USA'", 1 Wend 'Fecha o Recordset rst.Close |
A DAO possui ainda os métodos: FindFirst, FindNext, FindLast e FindPrevious eles localizam o primeiro registro, o último registro, o registro anterior ou o próximo registro em um objeto Recordset que satisfaça aos critérios de localização especificados e torna esse registro o registro atual.
A sintaxe para estes métodos é a seguinte:
Variável Objeto Recordset.{FindFirst | FindLast | FindNext | FindPrevious} critérios de localização
Cada um dos métodos Find começa sua pesquisa a partir do local e na direção especificados na tabela a seguir.
Método Find | Inicia a pesquisa no | Direção da pesquisa | ||
FindFirst | Início do conjunto de registros | Final do conjunto de registros | ||
FindLast | Final do conjunto de registros | Início do conjunto de registros | ||
FindNext | Registro atual | Final do conjunto de registros | ||
FindPrevious | Registro atual | Início do conjunto de registros |
A ADO possui somente o método : Find e sempre inicia a busca do registro atual. A direção da busca é fornecida com a utilização de parâmetros
A tabela a seguir mostra o equivalente em ADO para os métodos da DAO:
metodo DAO | ADO direção da busca |
FindFirst | adSearchForward (Se não estiver posicionado no primeiro registro, invoque o método MoveFirst antes do Find) |
FindLast | adSearchBackward (Se não estiver posicionado no último registro ,invoque o método l MoveLast antes do Find) |
FindNext | adSearchForward |
FindPrevious | adSearchBackward |
Existe uma diferença basica entre DAO e ADO para localizar registros com valor NULL.
Ao utilizar a DAO a sintaxe usada é:
"ColumnName Is Null" ou "ColumnName Is Not Null"
Como ADO não reconhece o operador Is devemos usar os operadores ( = ) ou ( <> ), assim ficamos com:
"ColumnName = Null" ou "ColumnName <> Null"
A DAO possui a propriedade NoMatch que é usada para saber se a busca foi bem sucedida ou não . ADO não possui a propriedade NoMatch , para obtermos o mesmo efeito na ADO devemos usar as propriedades BOF e EOF.
Usando o método Seek
DAO
Dim
db As DAO.Database Dim rst As DAO.Recordset 'Abre a base de dados Set db = DBEngine.OpenDatabase("C:\nwind.mdb") 'Abre o Recordset Set rst = db.OpenRecordset("order Details", dbOpenTable) 'Seleciona o indice rst.Index = "PrimaryKey" 'Busca pela registro onde OrderId=10255 e ProductId=16 rst.Seek "=", 10255, 16 'Se encontrou imprime If Not rst.NoMatch Then Debug.Print rst.Fields("Quantity").Value End If 'Fecha o Recordset rst.Close |
ADO
Dim cnn As New ADODB.Connection Dim rst As New ADODB.Recordset 'Abre uma conexão cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;" 'Selecione um índice ativo rst.Index = "PrimaryKey" 'Abre o Recordset rst.Open "Order Details", cnn, adOpenKeyset, adLockOptimistic, adCmdTableDirect 'Busca pela registro onde OrderId=10255 e ProductId=16 rst.Seek Array(10255, 16), adSeekFirstEQ 'Se Achou imprime If Not rst.EOF Then Debug.Print rst.Fields("Quantity").Value End If 'Fecha o Recordset rst.Close |
O método Seek é baseado em índices por isso ele deve ser indicado antes de acionar o método. Quando nada é informado o Jet utiliza a chave primária ( Primary Key ).
No exemplo para a ADO usamos uma função array para especificar os valores para as duas colunas como parte dos parâmetros KeyValues . Para especificar somente um valor não há necessidade de utilizar a função.
Para a ADO , como no caso anterior, devemos usar as propriedades BOF e EOF para verificar se a busca foi bem sucedida ou não.
Veja os
Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique
e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ?
|
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências: