UtterAccess.com
X   Site Message
(Message will auto close in 2 seconds)

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> What Is A Temp Table And How Do You Create Them, Office 2007    
 
   
hk1
post May 5 2012, 10:14 AM
Post #1

UtterAccess Veteran
Posts: 400



I think the answer to the first part of my question is actually pretty obvious, but what is a temp table? Do you literally create this table on the fly or is it one that you've created before hand and then you only use it temporarily?

It looks like some dbms's (such as oracle) actually have some kind of special provision for a temp tables. It's my understanding that MS Access does not. Is that correct?

And finally, I'm wondering what the easiest ways are to create temp tables. Can you take a DAO recordset and create the full table structure from it, then add the data from it?

Any other tips on using temp tables?
Go to the top of the page
 
+
Peter46
post May 5 2012, 10:27 AM
Post #2

UtterAccess VIP
Posts: 7,440
From: Oadby Leics, UK



You are correct. Access does not have temp tables. SO questions on how to create them have no meaning.

You can create and delete real tables as you wish and so you might regard such tables conceptually as temp tables. But you have to do the work. Nothing in Access recognises such tables.
Make-table queries are the most obvious way to create them in code, assuming ypu are transferring data to them at the same time.
Go to the top of the page
 
+
merlenicholson
post May 5 2012, 10:50 AM
Post #3

UtterAccess Veteran
Posts: 348
From: Tampa, Florida, USA - UTC -5:00



I think of a TEMP table as just a way to keep data needed in the middle of a process. Say I'm trying create a report that needs a final table that can be gathered by two separate processes. So you do the first part and do a make-table to hang on to the data for the second part. It happens (to me) all the time. Also sometimes it's necessary to break up a process if you have too many imbedded queries (queries using queries using queries).

So I have two personal rules about temporary tables: 1) Always use the characters TEMP in the table name. 2) Always delete the table at the end of the process and 3) If I discover a table hanging around with the word TEMP in it, I've forgotten to do 2).
Go to the top of the page
 
+
theDBguy
post May 5 2012, 11:32 AM
Post #4

Access Wiki and Forums Moderator
Posts: 48,612
From: SoCal, USA



Hi,

I usually avoid using temp tables, but they are necessary sometimes. If possible, I would recommend creating the tables beforehand and just fill them in with data and empty them out when done. This approach reduces possible "bloat" problems when compared to creating and deleting tables all the time.

Just my 2 cents... (IMG:style_emoticons/default/2cents.gif)
Go to the top of the page
 
+
projecttoday
post May 5 2012, 01:19 PM
Post #5

UtterAccess VIP
Posts: 5,139
From: Dunbar, WV



I might add it's a good practice to delete the records right before you fill the table, even if you have delete code elsewhere. Such temp tables reside in the front end database.

Also, if you have a "close database" button on your main form, you can put code there that will empty your temp tables, for what it's worth.
Go to the top of the page
 
+
Jeff B.
post May 5 2012, 03:02 PM
Post #6

UtterAccess VIP
Posts: 8,192
From: Pacific NorthWet



As a way to limit/reduce the bloat that DB mentions, consider creating a 'side' database, putting the "temp" table in there, and linking to that temp table. That way, if there's any bloat, it happens in the side db, not in your front-end db.
Go to the top of the page
 
+
dipetete
post May 5 2012, 04:10 PM
Post #7

UtterAccess Guru
Posts: 868
From: Bogotá - Colombia



As always everything is relative to the work you are doing.

I use both theDBguy and Jeff B. approaches for different things.

Other ways I handle temporary data are:
-. Using the Dictionary Object (very fast but rigid) <-- For example, for creting the table definitions in one step. TableDefs are slow, so I want to use them just once.
-. Creating matrices, export them in one step to Excel and reimporting them to Access (very fast and flexible) <-- For creating tables with the right data type automatically, or appending records from multiple sources into a single table...
-. Creating .xml files, importing them into Excel and finally importing them into Access. <-- for unstructured data

Also you can "fix" the bloating problem by just compacting and repairing the database (either manually or by code) after using several Temp tables created on the fly.

So, the "best" approach depends on what you are trying to accomplish, the way you are going to use temp tables, the number and size of the temp tables you are going to use, etc.

Regards,

Diego
Go to the top of the page
 
+
gemmathehusky
post May 6 2012, 01:39 PM
Post #8

UtterAccess VIP
Posts: 1,956
From: UK



i often use local tables as a temporary data store

my main tables will be in a linked be database

if i need to import a spreadsheet, or csv, i import that to a local temporary table (transfer text, or transfer spreadsheet commands) - validate the data as appropriate, and then append the new data to the real tables.

once you establish the "algorithm" you can import similar data files with the same mechanism
Go to the top of the page
 
+
hk1
post May 7 2012, 10:41 AM
Post #9

UtterAccess Veteran
Posts: 400



Thanks for all your contributions/opinions.

It looks to me like it's best to have your so-called temp tables pre-fabricated in whichever database you want them in (preferrably a local db separate from your frontend file). Or else have some kind of procedure that can generate the entire table complete with the correct indexes, primary key, etc.

What I'm actually trying to do is take a somewhat complicated query and convert it to a proper table. I've basically given up on this idea because there seems to be too many complications. Indexes and primary keys apparently can't be derived from a complicated query with Joins and Group By.

Here's some useful code I did piece together during my search:
CODE
Public Sub CopyTable(ByVal sourceTableName As String, ByVal destinationTableName As String, Optional bCopyData As Boolean = False)
On Error GoTo Err_Handler

    'Credit for this code goes to: http://stackoverflow.com/questions/1594096/how-to-copy-a-linked-table-to-a-local-table-in-ms-access-programmatically

    'Doesn't copy indexes or primary keys on Queries (which is probably to be expected)
    
    Dim cn As ADODB.Connection
    Dim cat As ADOX.Catalog
    Dim sourceTable As ADOX.Table
    Dim destinationTable As ADOX.Table
    
    Set cn = CurrentProject.Connection
    Set cat = New ADOX.Catalog
    Set cat.ActiveConnection = cn
    
    Set destinationTable = New ADOX.Table
    destinationTable.Name = destinationTableName
    
    Set sourceTable = cat.Tables(sourceTableName)
    
    Dim col As ADOX.Column
    For Each col In sourceTable.Columns
       Dim newCol As ADOX.Column
       Set newCol = New ADOX.Column
    
       With newCol
          .Name = col.Name
          .Attributes = col.Attributes
          .DefinedSize = col.DefinedSize
          .NumericScale = col.NumericScale
          .Precision = col.Precision
          .Type = col.Type
       End With
    
       destinationTable.Columns.Append newCol
    Next col

    Dim key As ADOX.key
    Dim newKey As ADOX.key
    
    Dim KeyCol As ADOX.Column
    Dim newKeyCol As ADOX.Column
    For Each key In sourceTable.Keys
       Set newKey = New ADOX.key
       newKey.Name = key.Name
       For Each KeyCol In key.Columns
          Set newKeyCol = destinationTable.Columns(KeyCol.Name)
          newKey.Columns.Append (newKeyCol)
       Next KeyCol
    
       destinationTable.Keys.Append newKey
    Next key

    cat.Tables.Append destinationTable
    
    Call copyTableIndexes(cn, cn, sourceTableName, destinationTableName)

    If bCopyData = True Then
        'Finally, copy data from source to destination table
        Dim sql As String
        sql = "INSERT INTO " & destinationTableName & " SELECT * FROM " & sourceTableName
        CurrentDb.Execute sql
    End If

Err_Handler:
   Set cat = Nothing
   Set key = Nothing
   Set col = Nothing
   Set sourceTable = Nothing
   Set destinationTable = Nothing
   Set cn = Nothing

   If Err.Number <> 0 Then
      MsgBox Err.Number & ": " & Err.Description, vbCritical, Err.Source
   End If
End Sub

Private Sub copyTableIndexes(ByRef srcConn As ADODB.Connection, ByRef dstConn As ADODB.Connection, srcTable As String, dstTable As String)
    
    Dim catSrc As New ADOX.Catalog, catDst As New ADOX.Catalog
    catSrc.ActiveConnection = srcConn
    catDst.ActiveConnection = dstConn
    
    Dim tblSrc As ADOX.Table, tblDst As ADOX.Table
    Dim idxSrc As ADOX.Index, idxDst As ADOX.Index
    Dim i As Integer
    
    Set tblSrc = catSrc.Tables(srcTable)
    Set tblDst = catDst.Tables(dstTable)
        
    For Each idxSrc In tblSrc.Indexes
        
        Set idxDst = New ADOX.Index
        
        idxDst.Name = idxSrc.Name
        idxDst.Clustered = idxSrc.Clustered
        'idxDst.IndexNulls = idxSrc.IndexNulls 'can't copy this one ?!
        idxDst.PrimaryKey = idxSrc.PrimaryKey
        idxDst.Unique = idxSrc.Unique
        For i = 0 To idxSrc.Columns.Count - 1
            idxDst.Columns.Append idxSrc.Columns(i).Name
            idxDst.Columns(idxSrc.Columns(i).Name).SortOrder = idxSrc.Columns(i).SortOrder
        Next
        On Error Resume Next   'just pass the indexes that I can't copy
        tblDst.Indexes.Append idxDst
        Set idxDst = Nothing
    Next
    
End Sub


Public Function RecordsInTable(ByVal sTableName As String, _
                            Optional ByRef dbIn As DAO.Database, _
                            Optional ByRef sDBPath As String) As Long
    If sTableName = "" Then Exit Function
    Dim db As DAO.Database, bClose As Boolean
    If Not dbIn Is Nothing Then
       Set db = dbIn
    ElseIf sDBPath <> "" Then
        
        If Dir(sDBPath) = "" Then
            If Left(sDBPath, 2) <> "\\" And Mid(sDBPath, 2, 1) <> ":" Then
                'Assume database is in currentproject directory
                sDBPath = CurrentProject.Path & "\" & sDBPath
            End If
        End If
        
        If Dir(sDBPath) = "" Then
            MsgBox "The database you specified cannot be found."
            Exit Function
        End If
        
        Set db = OpenDatabase(sDBPath) 'assumes blank password
        bClose = True

    Else
        Set db = CurrentDb
    End If
    
    If Not db Is Nothing Then
        If TableExists(sTableName, db) <> "" Then
            Dim r As DAO.Recordset
            Set r = db.OpenRecordset("SELECT Count(*) As RecordCount FROM " & sTableName, dbOpenDynaset, dbSeeChanges)
            If Not (r.EOF And r.BOF) Then
                RecordsInTable = r("RecordCount").Value
            Else
                RecordsInTable = 0
            End If
            r.Close
            Set r = Nothing
        Else
            RecordsInTable = -1
        End If
        If bClose = True Then db.Close
        Set db = Nothing
    Else
        RecordsInTable = -1
    End If
    
End Function


Public Function TableExists(ByVal sTableName As String, _
                            Optional ByRef dbIn As DAO.Database, _
                            Optional ByRef sDBPath As String) As String
                                
    'This Function returns "Local", "Linked", or ""
    
    If sTableName = "" Then Exit Function
    Dim db As DAO.Database
    If Not dbIn Is Nothing Then
       Set db = dbIn
       TableExists = TableExists2(sTableName, db)
       Set db = Nothing
    ElseIf sDBPath <> "" Then
        
        If Dir(sDBPath) = "" Then
            If Left(sDBPath, 2) <> "\\" And Mid(sDBPath, 2, 1) <> ":" Then
                'Assume database is in currentproject directory
                sDBPath = CurrentProject.Path & "\" & sDBPath
            End If
        End If
        
        If Dir(sDBPath) = "" Then
            MsgBox "The database you specified cannot be found."
            Exit Function
        End If
        
        'OpenDatabase Method: http://msdn.microsoft.com/en-us/library/bb243164(v=office.12).aspx
        Set db = OpenDatabase(sDBPath) 'assumes blank password
        TableExists = TableExists2(sTableName, db)
        db.Close
        Set db = Nothing

    Else
        Set db = CurrentDb
        TableExists = TableExists2(sTableName, db)
        Set db = Nothing
    End If
                            
End Function

Private Function TableExists2(ByVal sTableName As String, _
                                ByRef dbIn As DAO.Database) As String
     Dim i As Integer
     For i = 0 To dbIn.TableDefs.Count - 1
        If dbIn.TableDefs(i).Name = sTableName Then
            If dbIn.TableDefs(i).Connect <> "" Then
                TableExists2 = "Linked"
            Else
                TableExists2 = "Local"
            End If
        End If
    Next i
End Function

Go to the top of the page
 
+

Thank you for your support! Reply to this topicStart new topic

Jump To Forum:
 



RSS Go to Top  ·  Lo-Fi Version Time is now: 19th June 2013 - 10:57 AM

Tag cloud: