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:

  1. Usando o método Execute do objeto Connection.
  2. Usando o método Open do objeto Recordset.
  3. Usando o método Execute do objeto Command.

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:


José Carlos Macoratti