Erro "Não existe espaço em disco ou memória suficiente" ao efetuar uma operação numa tabela do Access

Avançado: requer codificação especializada, interoperabilidade e competências multiutilizadas.

Este artigo aplica-se apenas a uma base de dados do Microsoft Access (.mdb).

Sintomas

Quando efetua uma operação numa tabela, poderá receber a seguinte mensagem de erro se a operação criar um grande número de bloqueios de página: não existe espaço em disco ou memória suficiente.

Se executar uma consulta de ação numa tabela grande, poderá receber a seguinte mensagem de erro: Não existe espaço em disco ou memória suficiente para anular as alterações de dados que esta consulta de ação está prestes a efetuar.

Causa

Os bloqueios de página necessários para a transação excedem o valor MaxLocksPerFile, que é predefinido para 9500 bloqueios. O MaxLocksPerFilesetting é armazenado no registo do Windows.

Resolução

Importante

Esta secção, método ou tarefa contém passos que explicam como modificar o registo. No entanto, poderão ocorrer problemas graves se modificar o registo de forma incorreta. Por conseguinte, certifique-se de que segue estes passos cuidadosamente. Para maior segurança, faça uma cópia de segurança do registo antes de o modificar. Deste modo, pode restaurar o registo se ocorrer um problema. Para mais informações sobre como fazer uma cópia de segurança e restaurar o registo, clique no número de artigo que se segue para ver o artigo na Base de Dados de Conhecimento Microsoft:

322756 Como fazer uma cópia de segurança e restaurar o registo no Windows

Existem várias formas de contornar este problema:

  • Pode utilizar Regedit.exe para editar o registo e alterar permanentemente MaxLocksPerFilevalue.
  • Pode utilizar o SetOptionmethod do objeto DBEngine para alterar temporariamente o maxLocksPerFilevalue no código.
  • Se o erro ocorrer quando executar uma consulta de ação, pode modificar a consulta e definir a propriedade UseTransaction como Não.

Método 1: Alterar MaxLocksPerFile no registo

Utilize a Revisor de Registo para aumentar o valor MaxLocksPerFile na seguinte chave:

Para o Microsoft Access 2000, no Microsoft Access 2002 e no Microsoft Office Access 2003 que estão a ser executados num sistema operativo Windows de 32 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Jet 4.0

Para o Microsoft Access 2000, no Microsoft Access 2002 e no Microsoft Office Access 2003 que estão a ser executados num sistema operativo Windows de 64 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Jet 4.0

Para o Microsoft Office Access 2007 que está em execução num sistema operativo Windows de 32 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\ACE

Para o Microsoft Office Access 2007 que está em execução num sistema operativo Windows de 64 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\12.0\Access Connectivity Engine\Engines\ACE

Para o Microsoft Access 2010 que está em execução num sistema operativo Windows de 32 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\ACE

Para o Microsoft Office Access 2010 que está em execução num sistema operativo Windows de 64 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\ACE

Para Microsoft Access 2013 em execução num sistema operativo Windows de 32 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\15.0\Access Connectivity Engine\Engines\ACE

Para o Microsoft Office Access 2013 que está em execução num sistema operativo Windows de 64 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Access Connectivity Engine\Engines\ACE

Para o Microsoft Access 2016 que está em execução num sistema operativo Windows de 32 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\ACE

Para o Microsoft Office Access 2016 em execução num sistema operativo Windows de 64 bits:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Access Connectivity Engine\Engines\ACE

Tenha em atenção que este método altera a definição de registo para todas as aplicações que utilizam a versão 4.0 do motor de base de dados do Microsoft Jet.

Método 2: Utilizar SetOption para alterar MaxLocksPerFile Temporariamente

Nota

O código de exemplo neste artigo utiliza Objetos do Microsoft Data Access. Para que este código seja executado corretamente, tem de referenciar a Biblioteca de Objetos do Microsoft DAO 3.6. Para tal, clique em Referências no menu Ferramentas no Visual Basic Revisor e certifique-se de que a caixa de verificação Biblioteca de Objetos do Microsoft DAO 3.6 está selecionada.

A Microsoft fornece exemplos de programação apenas a título informativo, sem qualquer garantia expressa ou implícita, incluindo, sem limitações, as garantias implícitas de comercialização e/ou adequação a um fim específico. Este artigo pressupõe que o utilizador está familiarizado com a linguagem de programação demonstrada e as ferramentas utilizadas para criar e depurar procedimentos. Os técnicos de suporte da Microsoft podem ajudar a explicar a funcionalidade de um determinado procedimento, mas não modificarão estes exemplos para proporcionarem funcionalidades adicionais nem criarão procedimentos adaptados às suas necessidades específicas. O SetOptionmethod substitui temporariamente os valores das chaves do motor de base de dados do Microsoft Jet no registo. O novo valor permanece em vigor até que o altere novamente ou até que o objeto DBEngine seja fechado.

Nota

As alterações efetuadas à MaxLocksPerFilesetting através do método SetOption só estarão disponíveis através da sessão atual de Objetos de Acesso a Dados (DAO). As consultas executadas através da interface de utilizador do Microsoft Access continuarão a utilizar as definições no registo.

O seguinte exemplo de código define MaxLocksPerFile para 200 000 antes de executar uma operação de atualização dentro de uma transação:

Sub LargeUpdate()
   On Error GoTo LargeUpdate_Error
   Dim db As DAO.Database, ws As DAO.Workspace

' Set MaxLocksPerFile.
   DBEngine.SetOption dbMaxLocksPerFile, 200000

Set db = CurrentDb
   Set ws = Workspaces(0)

' Perform the update.
   ws.BeginTrans
   db.Execute "UPDATE BigTable SET Field1 = 'Updated Field'", _
         dbFailOnError

ws.CommitTrans

db.Close
   MsgBox "Done!"
   Exit Sub

LargeUpdate_Error:
   MsgBox Err & " " & Error
   ws.Rollback
   MsgBox "Operation Failed - Update Canceled"
   End Sub

Método 3: Definir a propriedade UseTransaction numa consulta de ação

Se uma consulta de ação armazenada causar o erro, pode definir a respetiva propriedade UseTransaction como Não. Tenha em atenção que, se o fizer, não poderá reverter as alterações se existir um problema ou um erro enquanto a consulta estiver em execução:

  1. Abra a consulta na vista Estrutura.
  2. No menu Ver, clique em Propriedades.
  3. Clique num espaço vazio na metade superior da janela de consulta para apresentar a caixa de diálogo Propriedades da Consulta.
  4. Defina UseTransactionproperty como Não.
  5. Guarde a consulta e feche-a.

Mais informações

O MaxLocksPerFilesetting no registo impede que as transações no motor de base de dados do Microsoft Jet excedam um valor especificado. Se uma transação tentar criar bloqueios que excedam o valor MaxLocksPerFile, a transação é dividida em duas ou mais partes e parcialmente consolidada.

Passos para reproduzir o problema

O exemplo seguinte utiliza um procedimento do Visual Basic para criar uma tabela com 10 000 registos e, em seguida, modifica a tabela para causar a mensagem de erro:

  1. Abra a base de dados de exemplo Northwind.mdb.
  2. Crie um módulo e, em seguida, escreva o seguinte procedimento:
Sub CreateBigTable()
   Dim db As Database, rs As Recordset
   Dim iCounter As Integer, strChar As String
   Set db = CurrentDb
   db.Execute "CREATE TABLE BigTable (ID LONG, Field1 TEXT(255), " & _
     "Field2 TEXT(255), Field3 TEXT(255), Field4 TEXT(255))", _
     dbFailOnError
   Set rs = db.OpenRecordset("BigTable", dbOpenDynaset)
   iCounter = 0
   strChar = String(255, " ")
   While iCounter <= 10000
      rs.AddNew
      rs!ID = iCounter
      rs!Field1 = strChar
      rs!Field2 = strChar
      rs!Field3 = strChar
      rs!Field4 = strChar
      rs.Update
      iCounter = iCounter + 1
   Wend
   MsgBox "Done!"
End Sub

  1. Para executar o procedimento, escreva a seguinte linha na janela Imediato e, em seguida, prima ENTER:

    CreateBigTable
    

    O procedimento cria uma tabela chamada BigTable com 10 000 registos.

  2. Guarde o módulo como Módulo1 e, em seguida, feche-o.

  3. Abra a tabela BigTable na vista Estrutura.

  4. Altere a propriedade FieldSize do Campo4 para 253.

  5. Guarde a tabela. Clique em Sim quando lhe for pedido que alguns dados possam ser perdidos.

    Tenha em atenção que, após algum tempo, recebe as seguintes mensagens de erro:

    Microsoft Access can't change the data type.
    There isn't enough disk space or memory.  
    
    Errors were encountered during the save operation. Data types were not changed. Properties were not updated.