web-dev-qa-db-fra.com

Vérifiez si la table d'accès existe

Je souhaite enregistrer les données IP, DateTime, Client et Refferer des visites de sites Web pour accéder à la base de données, mais je prévois de vous connecter chaque jour des données du journal dans des tables distinctes dans les journaux de 06.06.2010 seront connectés en 2010_06_06 Table nommée. Lorsque la date est modifiée, je créer une table nommée 2010_06_07. Mais le problème est que si cette table est déjà créée.

Toute suggestion comment vérifier si la table existe dans l'accès?

17
HasanG

Vous pouvez utiliser la table système cachée MSYSObjects pour vérifier si une table existe:

If Not IsNull(DlookUp("Name","MSysObjects","Name='TableName'")) Then
    'Table Exists

Cependant, je conviens que c'est une très mauvaise idée de créer une nouvelle table tous les jours.

Edit: Je devrais ajouter que les tables ont un type 1, 4 ou 6 et il est possible que d'autres objets d'un type différent d'avoir le même nom qu'un tableau, il serait donc préférable de dire:

If Not IsNull(DlookUp("Name","MSysObjects","Name='TableName' And Type In (1,4,6)")) Then
    'Table Exists

Cependant, il n'est pas possible de créer une table avec le même nom qu'une requête, de sorte que si vous avez besoin d'un coup d'œil pour tester un nom, il peut être préférable d'ajouter 5, qui est requis, à la liste de types.

38
Fionnuala

J'ai testé diverses méthodes pour déterminer si une table existe il y a plusieurs années. Voici le code pour tous comme je l'ai mis en œuvre, y compris ma routine de test simple.

Public Function TableExists(strTableName As String, Optional ysnRefresh As Boolean, Optional db As DAO.Database) As Boolean
' Originally Based on Tony Toews function in TempTables.MDB, http://www.granite.ab.ca/access/temptables.htm
' Based on testing, when passed an existing database variable, this is the fastest
On Error GoTo errHandler
  Dim tdf As DAO.TableDef

  If db Is Nothing Then Set db = CurrentDb()
  If ysnRefresh Then db.TableDefs.Refresh
  Set tdf = db(strTableName)
  TableExists = True

exitRoutine:
  Set tdf = Nothing
  Exit Function

errHandler:
  Select Case Err.Number
    Case 3265
      TableExists = False
    Case Else
      MsgBox Err.Number & ": " & Err.Description, vbCritical, "Error in mdlBackup.TableExists()"
  End Select
  Resume exitRoutine
End Function

Public Function TableExists2(strTableName As String, Optional ysnRefresh As Boolean, Optional db As DAO.Database) As Boolean
On Error GoTo errHandler
  Dim bolCleanupDB As Boolean
  Dim tdf As DAO.TableDef

  If db Is Nothing Then
     Set db = CurrentDb()
     bolCleanupDB = True
  End If
  If ysnRefresh Then db.TableDefs.Refresh
  For Each tdf In db.TableDefs
    If tdf.name = strTableName Then
       TableExists2 = True
       Exit For
    End If
  Next tdf

exitRoutine:
  Set tdf = Nothing
  If bolCleanupDB Then
     Set db = Nothing
  End If
  Exit Function

errHandler:
  MsgBox Err.Number & ": " & Err.Description, vbCritical, "Error in mdlBackup.TableExists1()"
  Resume exitRoutine
End Function

Public Function TableExists3(strTableName As String, _
     Optional db As DAO.Database) As Boolean
' Based on testing, when NOT passed an existing database variable, this is the fastest
On Error GoTo errHandler
  Dim strSQL As String
  Dim rs As DAO.Recordset

  If db Is Nothing Then Set db = CurrentDb()
  strSQL = "SELECT MSysObjects.Name FROM MSysObjects "
  strSQL = strSQL & "WHERE MSysObjects.Name=" & Chr(34) & strTableName & Chr(34)
  strSQL = strSQL & " AND MSysObjects.Type=6;"
  Set rs = db.OpenRecordset(strSQL)
  TableExists3 = (rs.RecordCount <> 0)

exitRoutine:
  If Not (rs Is Nothing) Then
     rs.Close
     Set rs = Nothing
  End If
  Exit Function

errHandler:
  MsgBox Err.Number & ": " & Err.Description, vbCritical, _
     "Error in TableExists1()"
  Resume exitRoutine
End Function

Public Sub TestTableExists(strTableName As String, intLoopCount As Integer)
  Dim dteStart As Date
  Dim i As Integer
  Dim bolResults As Boolean

  dteStart = Now()
  For i = 0 To intLoopCount
    bolResults = TableExists(strTableName, , CurrentDB())
  Next i
  Debug.Print "TableExists (" & intLoopCount & "): " & Format(Now() - dteStart, "nn:ss")

  dteStart = Now()
  For i = 0 To intLoopCount
    bolResults = TableExists2(strTableName, , CurrentDB())
  Next i
  Debug.Print "TableExists2 (" & intLoopCount & "): " & Format(Now() - dteStart, "nn:ss")

  dteStart = Now()
  For i = 0 To intLoopCount
    bolResults = TableExists3(strTableName, CurrentDB())
  Next i
  Debug.Print "TableExists3 (" & intLoopCount & "): " & Format(Now() - dteStart, "nn:ss")
End Sub
7
David-W-Fenton

Voici une autre solution, sera un peu plus rapide que de boucler sur toutes les tables.

Public Function doesTableExist(strTableName As String) As Boolean
    Dim db As DAO.Database
    Dim td As DAO.TableDef
    Set db = CurrentDb
    On Error Resume Next
    Set td = db.TableDefs(strTableName)
    doesTableExist = (Err.Number = 0)
    Err.Clear
End Function
7
KevenDenen

J'ai trouvé des tables système ou des tablefs de requête pour être peu fiable et d'introduire un comportement imprévisible dans les scripts où des tables sont créées régulièrement et abandonnées.

Basé sur mes résultats, mon hypothèse est que ces tables ne sont pas nécessairement mises à jour à l'instant exact a CREATE ou DROP est exécuté ou que les problèmes de concurrence m'empêchent d'obtenir un résultat précis.

J'ai trouvé la méthode suivante pour être plus fiable:

Public Function TableExists(theDatabase As Access.Application, _
    tableName As String) As Boolean

    ' Presume that table does not exist.
    TableExists = False

    ' Define iterator to query the object model.
    Dim iTable As Integer

    ' Loop through object catalogue and compare with search term.
    For iTable = 0 To theDatabase.CurrentData.AllTables.Count - 1
        If theDatabase.CurrentData.AllTables(iTable).Name = tableName Then
            TableExists = True
            Exit Function
        End If
    Next iTable

End Function

Il ne devrait y avoir aucun problème d'exécution itératant à moins d'une collection de tables étonnamment énormément énormément énormes.

2
Leo Orientis