ADO, ADOX  - Manual de Sobrevivência ...


Usando ADO para acessar Base de dados

Se você ainda não percebeu , existem 3 objetos distintos na ADO que trabalham em conjunto para fornecer toda a funcionalidade encontrada na DAO. Os três mosqueteiros são:

Toda a funcionalidade da ADO está dividida entre estes três objetos de maneira que muitas aplicações irão utilizar somente um subconjunto desta funcionalidade carregando na memória somente os objetos necessários para realizar determinada operação.

A seguir damos um resumo da funcionalidade de cada objeto:

1- ADO - Tratamento e gerenciamento da dados - O objeto ADO permite o acesso , tratamento e gerenciamento de dados em um banco de dados via um provedor OLE DB. 

2- ADOX - Definição de dados e segurança - O objeto ADOX contém propriedades e métodos para criar e modificar a estrutura de banco de dados, tabelas e consultas , permitindo também criar e modificar as contas de grupos e usuários implementando a segurança através de permissões aos objetos. A ADOX pode ser usada para definição de dados tanto no Access como no SQL Server.

3- JRO - Replicação e serviços do Jet Engine - O objeto JRO contém propriedades e métodos que permitem criar , modificar e sincronizar replicas. O JRO somente pode ser usado com base de dados Access e foi desenhado para ser utilizado especificamente com o provedor - Microsoft Jet 4.0 OLE DB Provider. 

Agora vamos procurar esclarecer as dúvidas mais comuns fornecendo uma orientação objetiva e sem rodeios. Este material é uma compilação de diversos artigos que podem ser encontrados na WEB.

ADO, ADOX , JRO - Manual de sobrevivência

1- Aonde eu posso encontrar a última versão da ADO e  ADOX ?

A ADO e a ADOX fazem parte do MDAC - Microsoft Data Access Components , e você pode fazer o download da última versão do MDAC no seguinte endereço: www.microsoft.com/data

2- Como posso saber qual a versão da MDAC eu tenho instalada em meu computador ? 

Para saber qual a versão atual da MDAC instalada em seu computador , faça o seguinte:

  1. Localize o arquivo msdadc.dll no diretório - C:\Arquivos de programas\Arquivos comuns\SYSTEM\ole db
  2. Clique com o botão direito do mouse sobre o arquivo e selecione a opção propriedades. Na caixa - Propriedades de msdadc.dll - selecione a aba Versão. Você verá a versão exibida , como na figura abaixo:

A versão da MDAC é obtida na tabela a seguir:

Versão da MDAC 

versão do arquivo msdadc.dll

MDAC 1.5c

1.50.3506.00

MDAC 2.0

02.00.3002.4

MDAC 2.0 SP1 / SP2

02.00.3002.23

MDAC 2.1.0.3513.2 (SQL)

02.10.3513.0

MDAC 2.1.1.3711.6 (IE 5)

02.10.3711.2

MDAC 2.1.1.3711.11 (GA)

02.10.3711.2

MDAC 2.1.2.4202.3 (GA) SP2

02.10.4202.0

MDAC 2.5 RTM (2.50.4403.12) 02.50.4403.0

3- Como posso saber se a MDAC esta instalada corretamente em meu computador ?

Faça o download e instale a ferramenta Component Checker da Microsoft no seguinte endereço: http://download.microsoft.com/download/dasdk/install/1.0/WIN98/EN-US/cc.exe 

O Component Checker é uma ferramenta que o ajuda a determinar a versão instalada e o diagnóstico da instalação do MDAC. As tarefas realizadas por esta ferramenta são:

1) Identifica a Instalação atual do MDAC no seu computador.   
2) Cria vários relatórios sobre os arquivos instalados pela MDAC identificando-os.      
3) Resolve conflitos de dll verificados durante a instalação.

4- Se eu estiver usando o Windows 2000 , ainda sim eu preciso instalar a MDAC ?

Não. O Windows 2000 já inclui o MDAC na versão 2.5 . A instalação é necessária nos sistemas Windows 95 , Windows 98 e NT 4.0.

5- Como eu posso criar um novo arquivo de banco de dados padrão Access usando a ADOX ?

Você pode criar um banco de dados access usando o método Create do objeto Catalog e especificando o "Engine Type" na string de conexão: 

Por exemplo:

oCat.Create  "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\temp\teste.mdb;" & _
                     "Jet OLEDB:Engine Type=5;"

Onde:
    Engine Type = 4 cria um banco de dados Access no formato 3.5 do Jet.
    Engine Type = 5 cria um banco de dados Access no formato 4.0 do Jet. (o padrão)

Obs: O acess97 não pode abrir um banco de dados criado na versão do Access 2000. 

6- Como eu posso redistribuir a ADO usando um arquivo CAB ?

Você pode  criar um arquivo CAB usando o arquivo MDAC_TYP.EXE( Leia o artigo que explica como fazer isto no endereço: http://support.microsoft.com/support/kb/articles/q189/6/71.asp ) através do Package and Deployment Wizard do Visual Basic.

No Windows 95 , você irá precisar instalar primeiro a DCOM95 , que requer um boot da máquina,  antes de instalar a MDAC 2.x. (O Internet Explorer 5.0 instala primeiro a DCOM95 antes de instalar o MDAC ). Para ambiente NT você precisa estar logado com direito de Administrador do sistema.

7- Onde eu encontro artigos da Microsoft sobre a ADO ?

Localize o site : http://support.microsoft.com/servicedesks/msdn/ e clique no link "Advanced Search". Selecione a seguir "ActiveX Data Objects" e digite uma ou mais palavras chaves. Clique no botão GO. 

8- Onde eu posso encontrar uma lista de Drivers ODBC e de Provedores OLE DB ?

Para obter uma lista de drivers ODBC leia o artigo no seguinte endereço:http://msdn.microsoft.com/library/psdk/dasdk/odbc7tkj.htm 

Para obter uma lista de Provedores OLE DB leia o artigo no seguinte endereço: http://msdn.microsoft.com/library/psdk/dasdk/mdap99m7.htm  

9- Por que quando eu tento me conectar a uma base de dados Access ocorre a seguinte mensagem de erro: - "ADO could not find the specified provider" ?

 Primeiro esteja certo de ter informado o nome correto do provedor OLE DB em sua string de conexão. Por exemplo:   Provider=Microsoft.Jet.OLEDB.4.0.

Lembre-se que ao instalar a MDAC 2.1 o provedor instalado é o JET 4.0 enquanto que se estiver instalado a MDAC 2.0 o provedor é o JET 3.51. Se precisar dos dois primeiro instale a MDAC 2.0 e então instale a MDAC 2.1 SP2 (que é a ultima revisão).

10- Eu posso utilizar o método Seek em um banco de dados do SQL Server ?

O SQL Server 6.5 ou 7.0 não suporta o método Seek nem o método Index do objeto Recordset. Você pode usar estes métodos em banco de dados do Access 2000 usando o Provedor OLE DB 4.0 para o JET. No exemplo abaixo usamos a tabela Produtos da base de dados teste.mdb para testar os métodos Seek e Index.

Dim oConn As ADODB.Connection
Dim oRS As ADODB.Recordset

' Cria uma nova conexão
Set oConn = New ADODB.Connection
oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\teste\teste.mdb;", "Admin", ""

' Cria um novo Recordset
Set oRS = New ADODB.Recordset
Set oRS.ActiveConnection = oConn
oRS.CursorLocation = adUseServer
oRS.Open "Produtos", oConn, adOpenKeyset, adLockPessimistic, adCmdTableDirect

' Verifique se os métodos  Index e Seek são suportados pelo Provedor
If oRS.Supports(adIndex) And oRS.Supports(adSeek) Then
    

    oRS.Index = "PrimaryKey"   
    Debug.Print "Index = " & oRS.Index
    
    oRS.MoveFirst
    oRS.Seek 4, adSeekFirstEQ
    If Not oRS.EOF Then
        Debug.Print oRS.Bookmark & " - " & oRS(1).Value
    End If
    
    oRS.Index = "CodigoProduto"  ' Nome do indice 
    Debug.Print "Index = " & oRS.Index
    
    oRS.MoveFirst
    oRS.Seek "1234", adSeekFirstEQ
    If Not oRS.EOF Then
        Debug.Print oRS.Bookmark & " - " & oRS(1).Value
    End If
Else
    Debug.Print "Os métodos Seek e Index não suportados."
End If

11- Eu posso abrir um cursor do tipo Dynamic em um banco  de dados Access ? 

O banco de dados Access não suporta cursores do tipo Dynamic . Por isso o provedor OLE DB para o JET não suporta o cursor do tipo adLockDynamic. Quando um cursor dynamic é requerido , o provedor irá retornar um cursor do tipo Keyset.

12- Ao chamar uma consulta em um banco de dados Access eu utilizo adCmdStoredProc ou adCmdTable ?

Se estiver usando o provedor Microsoft.Jet.OLEDB.4.0 você pode usar adCmdStoredProc.

Se estiver usando o provedor Microsoft.Jet.OLEDB.3.5.1 você deve usar adCmdTable.

 

13- Eu posso utilizar a propriedade MaxRecords em um banco de dados Access ?

O provedor OLE DB e o driver ODBC para o JET não suporta a propriedade MaxRecords. Para contornar o problema você pode usar a palavra chave TOP. Exemplo:

SELECT TOP 2 CodigoID, Nome, Endereco FROM Teste ORDER BY Nome;
ou

SELECT TOP 20 PERCENT CodigoID,Nome, Endereco FROM Teste ORDER BY Nome;

 

 

14- Ao utilizar a propriedade RecordCount em um Recordset eu sempre obtenho o valor -1 , Por que ?

 

A ADO utiliza como padrão um Recordset server-side (lado do servidor) com o cursor to tipo forward-only (adOpenForwardOnly), e este cursor não suporta a propriedade Recordcount. 

 

Para usar a propriedade RecordCount corretamente, defina o cursor como do tipo adOpenKeyset ou adOpenStatic.(Não utilize o cursor adOpenDynamic).

 

Se você criar um Recordset Client-side ( lado do cliente), então a ADO define automaticamente o tipo de cursor para Static (adOpenStatic) e a propriedade RecordCount irá funcionar corretamente.

 

15- Como criar um Recordset ADO desconectado ?

 

A primeira coisa a fazer para criar um Recordset ADO desconectado é definir a propriedade CursorLocation do objeto Recordset como adUseClient e a seguir abrir o Recordset.

 

Defina a conexão ativa (ActiveConection) do Recordset como nothing. Não feche o Recordset.(Não use close). 

 

Pronto você criou um recordset ADO desconectado. 

Vejamos um exemplo criando um Recordset Desconectado em páginas ASP:

<@ Language ="VBScript"

<%Option Explicit

Response.Expires=0

%>

<!-#include file="advobs.inc"-->

<%

Dim objCon , rs , sql 

 

set objCon = Server.CreateObject("ADODB.Connection")

objCon.Open "Data Source=teste;User ID=;Password=;"

 

Set rs = Server.CreateObject("ADODB.Recordset")

 

'Configura o recordset

rs.CursorLocation = adUseClient

rs.CursorType = adOpenStatic

rs.LockType = adLockReadOnly

 

sql = "Select * from teste"

 

'Desabilita a conexão ativa

rs.Open sql , objCon,,,adCmdText

set rs.ActiveConnection = Nothing

.....

.....

%>

 

 

 

16- Toda a vez que eu tento utilizar o método Find do objeto Recordset eu obtenho a seguinte mensagem de erro: "This application is using arguments that are of the wrong type, out of acceptable range or in conflict with one another". Por que ?

 

Se voce estiver usando a versão 2.1 da ADO , o método Find do objeto Recordset estará limitado a somente uma coluna por critério ,e , se você tentar usar dois ou mais colunas (campos, via declaração AND) com o critério irá obter a mensagem de erro descrita.

 

 

 

17 - É possível criar um Recordset hierárquico via código ?

 

Sim , você pode criar um objeto hierárquico via código. Basta especificar o Provedor como "msdatashape" e o Data Provider como none na sua string de conexão: Ex:

 

"provider=msdatashape;data provider=none"

 

Vejamos um exemplo :

 

Private Sub Command1_Click()

Dim rs As New ADODB.Recordset
Dim rsCh As ADODB.Recordset
Dim rsGrndCh As ADODB.Recordset

rs.ActiveConnection = "provider=msdatashape;data provider=none;"

'cria uma tabela 

rs.Open " SHAPE APPEND new adInteger As PID, " & _
" New adVarChar(10) As StudentName, " & _
"((SHAPE APPEND new adInteger As ChID, " & _
" New adVarChar(10) As Course, " & _
"((SHAPE APPEND new adInteger As GrndChID, " & _
" New adBSTR As Description) RELATE " & _
" ChID TO GrndChID) As GrandChild) RELATE PID TO ChID) " & _
"AS Child" , , adOpenStatic, adLockOptimistic

'Inclui um registro de exemplo no recordset pai

rs.AddNew Array("PID", "StudentName"), Array(1, "Jim Smith")

' Inclui dois registros filhos relacionados com o registro pai original
Set rsCh = rs("Child").Value
For i = 0 To 1
rsCh.AddNew Array("ChID", "Course"), Array(1, "Course #1" & i)

'Inclui dois registros (Gran-child)filhos para cada registro filho  
Set rsGrndCh = rsCh("GrandChild").Value
For j = 1 To 2
  rsGrndCh.AddNew Array("GrndChID", "Description"), _
  Array(i, "Description" & Str(j))
Next
Next

Set MSH1.DataSource = rs

MsgBox "Concluido com Sucesso..."

rs.Close
rsCh.Close
rsGrndCh.Close

End Sub

Voce precisa referenciar a ADO no projeto ( Microsoft ActiveX Data Objects 2.0 Library ) ; precisa usar o componente Microsoft Hierarchical FlexGrid Control 6.0 com o nome de MSH1.

Para maiores informações leia o artigo: 
Q196029
-
HOWTO: Create Hierarchical Recordsets Programmatically

 

18 - Como o método MoveFirst trabalha em um Recordset somente-para-frente(Forward-Only) do lado do servidor (Server-Side) ?

Dependendo do driver ODBC ou do Provedor OLE DB , MoveFirst executa novamente o comando SQL para o recordset somente-para-frente (Forward-Only). Portanto você deve ter cuidado para não abrir este tipo de Recordset e então acionar o método Movefirst , pois estará rodando o comando SQL duas vezes.

 

 

Para Recordsets do lado do cliente (Client Side) , o tipo do Cursor sempre é do tipo Static. Daí o recordset estará apto a executar um MoveFirst sem ter que executar novamente a consulta SQL.

 

 

19 - Ainda posso usar o método Seek com ADO ? 

O método Seek é muito popular e é usado para acessar um determinado registro em uma tabela do banco de dados. (Não quer dizer que seja o melhor método para fazer isso). O método opera abrindo uma tabela diretamente e procurando pelo registro usando um índice pré-definido. 

Se você for usar a DAO deverá abrir o banco de dados , especificar o nome do índice e executar o método seek passando uma expressão para qualificar a busca e uma lista de valores para busca que deverão coincidir com o registro procurado. Vejamos um exemplo usando a DAO:

 

 Dim db As DAO.Database

 Dim rst As DAO.Recordset

 

 Set db = DAO.DBEngine.OpenDatabase(DatabasePath$, False, False)

 Set rst = db.OpenRecordset("Teste", dbOpenTable)

  With rst

     .Index = "PrimaryKey"

     .Seek "=", 2

      MsgBox !Nome & " " & !Sobrenome

  End With

    

A utilização do método Seek com ADO só foi possível com o advento do Access 2000 e da versão 4.0 do Jet. Só o Jet suporta índices e o método Seek. A utilização no entanto é um pouco diferente. Ao utilizar a ADO você abre uma conexão usando um cursor do lado do cliente ( adUseClient ) e, como a ADO precisa abrir a tabela diretamente você deve usar a constante adCmdTableDirect. Com a ADO você deve passar um vetor de valores do tipo variant e não uma lista de valores para comparação com o índice. Vejamos um exemplo:

 

 Dim conn As ADODB.Connection

 Dim rst As ADODB.Recordset

  Set conn = New ADODB.Connection

  With conn

     ' especifica o provedor Jet

    .Provider = "Microsoft.Jet.OLEDB.4.0"

     ' Leitura/gravaçao

    .Mode = adModeReadWrite

    .ConnectionString = "data source=" & DatabasePath$

    .Open

  End With

  Set rst = New ADODB.Recordset

  With rst

    .Index = "PrimaryKey"

     ' Seek somente é suportado usando adUseServer

    .CursorLocation = adUseServer

     ' Abre o recordset usando adCmdTableDirect

     .Open "Teste", conn, adOpenKeyset,adLockOptimistic, adCmdTableDirect

     .Seek Array(2), adSeekFirstEQ

 

      MsgBox !Nome & " " & !Sobrenome

  End With

 

Lembre-se que embora o Seek é um método rápido para localizar dados de um tabela em um banco de dados Access. Ele deve ser usado somente para tabelas pequenas, pois o tem que carregar todo conteúdo do índice da tabela na memória. Além disto Seek é ineficiente para banco de dados remotos e não é suportado pelo SQL Server ou Oracle.

 

 

20 - O que mudou na edição de dados com a ADO ?

 

Quando você utilizava a DAO para editar um registro percorria a seguinte sequência: Abria o recordset , ativava o método Edit , editava os dados e executava o método Update. Veja exemplo a seguir:

 

Dim db As DAO.Database

Dim rst As DAO.Recordset

  Set db = DAO.DBEngine.OpenDatabase(DatabasePath$,False, False)

  Set rst = db.OpenRecordset("teste")

  rst.Edit

  rst!Nome = "Macoratti"

  rst.Update

End Sub

 

Algumas coisas mudaram com a ADO. 

  1. Primeiro lembre-se que: A ADO não suporta o método Edit 

  2. Segundo : quando estiver usando ADO você deve ter em mente que primeiro a ADO irá abrir um recordset somente-leitura como padrão, então teremos que definir o tipo de bloqueio e o tipo do cursor para tornar a edição de dados possível; 

  3. Terceiro: com a ADO você não precisa  usar o método Update , basta mover-se para o próximo registro e a ADO irá atualizar o registro.( Com a DAO se você não utilizar o método Update a sua edição era descartada.)

 

Dim conn As ADODB.Connection

Dim rst As ADODB.Recordset

  Set conn = New ADODB.Connection

  With conn

     'Define o provedor Jet

    .Provider = "Microsoft.Jet.OLEDB.4.0"

    .Mode = adModeReadWrite   ' Read/Write.

    .ConnectionString = "data source=" & DatabasePath$

    .Open

  End With

  Set rst = New ADODB.Recordset

  rst.Open "Teste", conn, adOpenKeyset, adLockOptimistic

  'Note que não usamos o método Edit

  rst!Nome = "Macoratti"

  'Se você utilizar um movenext o método Update não é necessário

  rst.Update

End Sub

 

Vai continuar... ;-)