2010-06-06 5 views
14

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 journaliser les données de journalisation dans des tables distinctes dans les journaux d'exemple du 06.06.2010 connecté en 2010_06_06 table nommée. Lorsque la date est modifiée, je crée une table nommée 2010_06_07. Mais le problème est si cette table est déjà créée.Vérifier si la table d'accès existe

Des suggestions pour vérifier si la table existe dans Access?

+8

Vous pouvez envisager d'utiliser une table puis d'utiliser une requête paramétrée pour générer vos vues "quotidiennes". Cela vous donnera plus de flexibilité. Par exemple, que se passe-t-il si vous voulez voir les résultats à la semaine? Avec une requête, il s'agit d'un simple changement de date pour les paramètres. Si vous aviez sept tables, vous devez créer physiquement une requête union avec les tables spécifiques. – AMissico

Répondre

32

Vous pouvez utiliser les MSysObjects de table système caché pour vérifier si une table existe:

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

Cependant, je suis d'accord qu'il est une très mauvaise idée de créer une nouvelle table tous les jours.

EDIT: Je dois 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 que d'une table, 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, donc si vous avez besoin de rechercher un nom, il est préférable d'ajouter 5, c'est-à-dire query, au Type liste.

+0

J'ai développé un peu la réponse. – Fionnuala

+0

Merci. Ce serait plus simple s'il y avait une requête sql pour cela mais je pense qu'il n'y en a pas:) ( –

+10

Il y a: SELECT [Nom] FROM MSysObjects OERE [Nom] = 'TableName' et Type In (1,4, 6) – Fionnuala

6

Voici une autre solution, qui sera un peu plus rapide que de boucler 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

J'ai testé différentes méthodes pour déterminer si une table existe depuis plusieurs années. Voici le code pour chacun d'entre eux que j'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 
+0

Les tablesExists & TableExists2 fonctionnent sur des tables liées (mysql odbc), mais TableExists3 ne l'est pas. – Mallow

2

J'ai trouvé l'interrogation des tables système ou TableDefs peu fiables et d'introduire un comportement imprévisible dans les scripts où tables sont régulièrement créées et abandonnées. Sur la base de mes résultats, mon hypothèse est que ces tables ne sont pas nécessairement mises à jour à l'instant exact où un CREATE ou DROP est exécuté, ou que les problèmes de simultanéité 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 devrait y avoir aucun problème d'exécution à moins d'itération d'une collection renversante énorme de tables.

Questions connexes