2010-06-06 23 views
14

Quiero registrar datos de IP de las visitas del sitio, fecha, cliente y datos de referencia para acceder a la base de datos, pero estoy planificando registrar todos los días los datos de registro en tablas separadas en los registros de ejemplo para 06.06.2010. ha iniciado sesión en 2010_06_06 tabla nombrada. Cuando se cambie la fecha, crearé una tabla llamada 2010_06_07. Pero el problema es si esta tabla ya está creada.Comprobar si existe tabla de acceso

¿Alguna sugerencia sobre cómo verificar si existe una tabla en Access?

+8

Es posible que desee considerar el uso de una tabla y luego utilizar una consulta parametrizada para generar sus vistas "diarias". Esto te dará una mayor flexibilidad. Por ejemplo, ¿qué pasa si quieres ver los resultados por semana? Con una consulta, es un simple cambio de fecha para los parámetros. Si tuviera siete tablas, tendría que crear físicamente una consulta de unión con las tablas específicas. – AMissico

Respuesta

32

Puede utilizar los MSysObjects tabla del sistema ocultas para comprobar si existe una tabla:

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

Sin embargo, estoy de acuerdo que es una muy mala idea para crear una nueva tabla de todos los días.

EDIT: Debo añadir que las tablas tienen un tipo 1, 4 o 6 y es posible que otros objetos de un tipo diferente de tener el mismo nombre que una tabla, por lo que sería mejor decir:

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

Sin embargo, no es posible crear una tabla con el mismo nombre que una consulta, por lo que si necesita una búsqueda para probar un nombre, puede ser mejor agregar 5, es decir, consultar al Tipo lista.

+0

Expandí un poco sobre la respuesta. – Fionnuala

+0

Gracias. Sería más fácil si hubiera una consulta SQL para esto, pero creo que no existe tal cosa:) ( –

+10

) Hay: SELECCIONE [Nombre] FROM MSysObjects DONDE [Nombre] = 'TableName' Y Escriba In (1,4, 6) – Fionnuala

6

Aquí hay otra solución, será un poco más rápido que recorrer todas las tablas.

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

He probado varios métodos para saber si existe una tabla hace varios años. Aquí está el código para todos ellos, tal como lo implementé, incluida mi rutina de prueba 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

TableExists y TableExists2 funcionan en tablas vinculadas (mysql odbc); TableExists3 no obstante. – Mallow

2

he encontrado consultar las tablas del sistema o TableDefs ser poco fiables e introducir un comportamiento impredecible en scripts en las tablas se crean con regularidad y cayeron.

Según mis resultados, mi hipótesis es que estas tablas no se actualizan necesariamente en el instante exacto en que se ejecuta CREATE o DROP, o que los problemas de concurrencia me impiden obtener un resultado preciso.

He encontrado el siguiente método sea más 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 

No debe haber ningún problema de tiempo de ejecución iterando a menos que haya un asombrosamente enorme colección de tablas.

Cuestiones relacionadas