2010-06-06 4 views
14

Desidero registrare i dati di IP, datetime, client e refferer delle visite al sito Web per accedere al database ma sto pianificando di registrare ogni giorno i dati del registro in tabelle separate nei log di esempio per 06.06.2010 saranno login 2010_06_06 tabella denominata. Quando viene cambiata la data creerò una tabella denominata 2010_06_07. Ma il problema è se questa tabella è già stata creata.Verificare se esiste una tabella di accesso

Qualche suggerimento su come verificare se la tabella esiste in Access?

+8

È possibile prendere in considerazione l'utilizzo di una tabella, quindi utilizzare una query con parametri per generare le visualizzazioni "giornaliere". Questo ti darà una maggiore flessibilità. Per esempio, cosa succede se vuoi vedere i risultati entro la settimana? Con una query, è una semplice modifica della data per i parametri. Se avessi sette tabelle, dovresti creare fisicamente una query di unione con le tabelle specifiche. – AMissico

risposta

32

È possibile utilizzare i nascoste MSysObjects tabella di sistema per verificare se esiste una tabella:

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

Tuttavia, sono d'accordo che si tratta di una pessima idea di creare una nuova tavola ogni giorno.

EDIT: devo aggiungere che le tabelle hanno un tipo 1, 4 o 6 ed è possibile per altri oggetti di un tipo diverso di avere lo stesso nome di una tabella, quindi sarebbe meglio dire:

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

Tuttavia, non è possibile creare una tabella con lo stesso nome di una query, quindi se è necessario cercare un nome per verificare un nome, è consigliabile aggiungere 5, che è una query, al tipo elenco.

+0

Ho ampliato un po 'la risposta. – Fionnuala

+0

Grazie. Sarebbe più facile se ci fosse una query sql per questo, ma penso che non ci sia una cosa del genere:) ( –

+10

Esiste: SELECT [Nome] FROM MSysObjects DOVE [Nome] = 'TableName' e Type In (1,4, 6) – Fionnuala

6

Ecco un'altra soluzione, sarà un po 'più veloce del ciclo su tutte le tabelle.

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

Ho provato vari metodi per scoprire se un tavolo esiste diversi anni fa. Ecco il codice per tutti quelli che ho implementato, inclusa la mia semplice routine di test.

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

TableExists e TableExists2 funzionano su (mysql odbc) tabelle collegate; TableExists3 non tuttavia. – Mallow

2

ho trovato l'interrogazione di tabelle di sistema o TableDefs di essere inaffidabile e introdurre un comportamento imprevedibile negli script in cui le tabelle vengono regolarmente creati e rilasciati.

In base ai miei risultati, la mia ipotesi è che queste tabelle non siano necessariamente aggiornate nell'istante esatto in cui viene eseguito un CREATE o DROP o che i problemi di concorrenza impediscano di ottenere un risultato accurato.

ho trovato il seguente metodo per essere più affidabile:

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 

Non ci dovrebbe essere alcun problema runtime iterazione a meno che non v'è un incredibilmente enorme collezione di tavoli.