ASP
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:
- Usando o método Execute do objeto Connection.
- Usando o método Open do objeto Recordset.
- 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 outrousuá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
<font size="2" face="Verdana"> Dim db As DAO.Database </font> <font size="2" face="Verdana"> Dim rst As DAO.Recordset </font> <font color="#008000" size="2" face="Verdana"> 'Abrindo a base de dados</font> <font size="2" face="Verdana"> Set db = DBEngine.OpenDatabase("C:\nwind.mdb") </font> <font size="2" face="Verdana"> </font><font color="#008000" size="2" face="Verdana"> 'Abrindo o Recordset</font> <font size="2" face="Verdana"> Set rst = db.OpenRecordset("Customers", dbOpenDynaset) </font> <font size="2" face="Verdana"> </font><font color="#008000" size="2" face="Verdana"> 'Procurando o primeiro cliente cujo pais seja 'USA'</font> <font size="2" face="Verdana"> rst.FindFirst "Country = 'USA'" </font> <font size="2" face="Verdana"> </font><font color="#008000" size="2" face="Verdana">'Agora imprimimos os codigos p/os clientes cujo país encontrado foi <strong>USA</strong></font> <font size="2" face="Verdana"> While Not rst.NoMatch </font> <font size="2" face="Verdana"> Debug.Print rst.Fields("CustomerId").Value </font> <font size="2" face="Verdana"> rst.FindNext "Country = 'USA'" </font> <font size="2" face="Verdana"> Wend </font> <font color="#008000" size="2" face="Verdana"> 'Fechando o Recorset</font> <font size="2" face="Verdana"> rst.Close </font> |
ADO
<font size="2" face="Verdana"> Dim cnn As New ADODB.Connection </font> <font size="2" face="Verdana"> Dim rst As New ADODB.Recordset </font> <font color="#0000FF" size="2" face="Verdana"> 'Criando uma instância do objeto Connection</font><font size="2" face="Verdana"> </font> <font size="2" face="Verdana"> cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;" </font> <font color="#0000FF" size="2" face="Verdana"> 'Abrindo o Recordset</font><font size="2" face="Verdana"> </font> <font size="2" face="Verdana"> rst.Open "Customers", cnn, adOpenKeyset, adLockOptimistic </font> <font color="#0000FF" size="2" face="Verdana"> 'Procurando o primeiro cliente cujo pais seja 'USA'</font> <font size="2" face="Verdana"> rst.Find "Country='USA'" </font> <font color="#0000FF" size="2" face="Verdana"> 'Agora imprimimos os codigos p/os clientes cujo país encontrado é <strong>USA</strong></font> <font size="2" face="Verdana"> While Not rst.EOF </font> <font size="2" face="Verdana"> Debug.Print rst.Fields("CustomerId").Value </font> <font size="2" face="Verdana"> rst.Find "Country='USA'", 1 </font> <font size="2" face="Verdana"> Wend </font> <font color="#0000FF" size="2" face="Verdana"> 'Fecha o Recordset</font> <font size="2" face="Verdana"> rst.Close </font> |
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 MoveFirstantes do Find) |
FindLast | adSearchBackward (Se não estiver
posicionado no último registro ,invoque o método l MoveLastantes 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
<font size="2" face="Verdana">Dim cnn As New ADODB.Connection </font> <font size="2" face="Verdana"> Dim rst As New ADODB.Recordset </font> <font size="2" face="Verdana"> <strong> 'Abre uma conexão</strong></font> <font size="2" face="Verdana"> cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\nwind.mdb;" </font> <font size="2" face="Verdana"> <strong> 'Selecione um índice ativo</strong></font> <font size="2" face="Verdana"> rst.Index = "PrimaryKey" </font> <font size="2" face="Verdana"> <strong> 'Abre o Recordset</strong></font> <font size="2" face="Verdana"> rst.Open "Order Details", cnn, adOpenKeyset, adLockOptimistic, adCmdTableDirect </font> <font size="2" face="Verdana"> '<strong>Busca pela registro onde OrderId=10255 e ProductId=16</strong></font> <font size="2" face="Verdana"> rst.Seek Array(10255, 16), adSeekFirstEQ </font> <font size="2" face="Verdana"> <strong> 'Se Achou imprime</strong></font> <font size="2" face="Verdana"> If Not rst.EOF Then </font> <font size="2" face="Verdana"> Debug.Print rst.Fields("Quantity").Value </font> <font size="2" face="Verdana"> End If </font> <font size="2" face="Verdana"><strong> 'Fecha o Recordset</strong></font> <font size="2" face="Verdana"> rst.Close </font> |
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.
Fonte: Jose Carlos Macoratti