My Assistant
![]() ![]() |
|
|
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? |
|
|
|
May 5 2012, 10:27 AM
Post
#2
|
|
|
UtterAccess VIP Posts: 7,397 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. |
|
|
|
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). |
|
|
|
May 5 2012, 11:32 AM
Post
#4
|
|
|
Access Wiki and Forums Moderator Posts: 48,095 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) |
|
|
|
May 5 2012, 01:19 PM
Post
#5
|
|
|
UtterAccess VIP Posts: 5,119 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. |
|
|
|
May 5 2012, 03:02 PM
Post
#6
|
|
|
UtterAccess VIP Posts: 8,170 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.
|
|
|
|
May 5 2012, 04:10 PM
Post
#7
|
|
|
UtterAccess Guru Posts: 857 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 |
|
|
|
May 6 2012, 01:39 PM
Post
#8
|
|
|
UtterAccess VIP Posts: 1,911 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 |
|
|
|
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 Top · Lo-Fi Version | Time is now: 24th May 2013 - 01:58 PM |