I am using the following code to insert data in an access table from SQL using a recordset. This table is further used for other operations. While this is inserting the data into the table perfectly, the time taken by this huge. Should I use any other method to insert data into the table to reduce the time taken?
Do Until rs.EOF
DoCmd.RunSQL "INSERT INTO Table (Alpha,Beta,Gamma) VALUES(" & _
rs.Fields(0).Value & ",'" & rs.Fields(1).Value & "'," & rs.Fields(2).Value _
& " );"
rs.MoveNext
Loop
Create a linked table to the SQL table, say it's called MyLinkedTable
Create an Append query to append to your local Access table from your linked table. It will look something like this: INSERT INTO MyAccessTable (Field1,Field2...) SELECT Field1,Field2... FROM MyLinkedTable;
If you could select the data in the SQL UPDATE statement instead looping in VBA it would take a fraction of the time as all the work would be done by the server side.
You just need to do an INSERT INTO SELECT. We need more information on your RecordSet but you probably do not need it.
'Here we go, with just one line!
DoCmd.RunSQL "INSERT INTO Table (Alpha,Beta,Gamma) SELECT column1, column2, column2 FROM YourTable"
The SELECT statement is probably the same as the one you used for opening your Recordset.
Good luck!
Related
I have written a simple code to loop through rows and insert values in column A (that is column containing full name) into an SQL Table. Something like this:
For i = 1 to LastRow
Command.CommandText = "INSERT INTO [TABLE] [Col1] VALUES ('" & Sheets("Sheet1").Cells(i, 1).Value & "')"
Next i
Issue arises when we have names like [O'Connell], which obviously creates a Bobby Table issue.
Are there any clever workarounds to avoid this?
Thanks
N.B. The full name is inserted from another SQL Table. In other words, perhaps a little difficult to edit.
You could use Replace to remove the problem character:
Command.CommandText = "INSERT INTO [TABLE] [Col1] VALUES ('" & _
Replace(Sheets("Sheet1").Cells(i, 1).Value,"'","") & "')"
I have a Staff Recruitment Database. When all formalities are complete I click a button and basic data is appended to the (recruited) Staff Database .
I also have data for the shift the recruit will work: Hours, Rate of pay etc. This goes into a Linked table.
To append this data I need to know the Primary Key of the recruit. How can I append the data automatically without looking at the table where the basic data is to find the PK?
I'm using INSERT INTO. Staff Database contains the main Staff table and the linked Shifts table.
If the "main" table has an AutoNumber field as its Primary Key then immediately after performing the INSERT INTO statement you can use some code like this to retrieve the PK value you just inserted:
Dim rst AS DAO.Recordset, newPK as Long
Set rst = CurrentDb.OpenRecordset("SELECT ##IDENTITY", dbOpenSnapshot)
newPK = rst(0).Value
rst.Close
Set rst = Nothing
You can then use the newPK value as a foreign key in the related tables.
Edit re: using the new value
Based on the code sample in your comment, try this instead:
strSQL = _
"INSERT INTO tblShifts (StartDt, [To], Hours, StaffLookup) " & _
"IN ""C:\__tmp\Staff.accdb"" " & _
"SELECT qryAdd.DateStarted, qryAdd.To, qryAdd.Hours, " & newPK & " AS StaffLookup FROM qryAdd"
If [tblShifts] really is a linked table then you shouldn't need to use the IN (mydatabase) clause because a linked table will behave just like a local table in this case. Note the corrections to the syntax as well, especially the bracketing of [To] which is a reserved word in Access.
Think I have got a solution. I can retrieve the PK into the recruitment db like this:
DoCmd.RunSQL "INSERT INTO tblCBSStaffLookup ( StaffLookupCBS, NINO ) " & _
"SELECT tblStaff.ID, tblStaff.NINO " & _
"FROM tblStaff IN 'C:\Users\Peter.Home-PC\Documents\NEMS\Databases\Frontends\Staff.accdb' " & _
"WHERE (((tblStaff.NINO)=[Forms]![frmSuccess]![NINO])) "
tblCBSStaffLookup is a table I have now made in the recruitment db to collect the PK and NINO.
WHERE matches the newly arrived NINO to a form in the recruitment db which already has the NINO. I have set up constraints to make sure that NINO's are valid. I have also set up a query in the recruitment db to retrive all NINO's from the main db, so that new recruits don't get added the the main db twice.
I have tried this with ALTER TABLE to create the column followed by INSERT INTO. This kind of works, except each subsequent column starts after the previous column has ended. I guess this is how insert into works, so is there a workaround or another query I can build?
I have been trying with updates but its not working out.
For reference, these were the alter/insert queries i used.
SQL = "ALTER TABLE [results] ADD COLUMN [" & fld.Name & "_result] TEXT(25)"
db.Execute SQL
SQL = "INSERT INTO [results] ([" & fld.Name & "_result]) SELECT [Result] As
[" & fld.Name & "_result] FROM [newtable]"
db.Execute SQL
Your insert statement assumes that the results table has only one column that you need to insert data into. This is unlikely to be true, if the table already had other columns before you executed the ADD COLUMN.
You will need to keep track of the columns in the results table, and provide data (or a default value) for each column.
It is rather unusual to expand a table's structure from inside an application. What are you trying to accomplish? Are you sure you can't accomplish it better by defining fixed tables and then adding data from your application?
UPDATE
Okay, I think I understand what you're describing. On the first iteration, the ALTER TABLE creates the first column. The INSERT adds a bunch of rows that have data in this first column.
On the second interation, the ALTER TABLE creates a second column. The INSERT creates a whole bunch of new rows, but only the second column is populated. The first column is all NULL because you didn't provide values for it. And so on and so forth for the third and subsequent iterations.
If your actual intention is to duplicate the source table and its data, then you should create your results table in a single pass. You know the column structure, right? Use a CREATE TABLE statement. Then write a single INSERT statement somewhat like the following:
INSERT INTO [results]
([field1_result], [field2_result], [field3_result])
SELECT [Result] As
[field1_result, [field2_result], [field3_result]]
FROM [newtable]
Is this what you have in mind?
Before you enter into the loop create your [results] table as
SQL = "CREATE TABLE [results] SELECT [primary_key] FROM [newtable]"
db.Execute SQL
Then at every iteration of the loop execute
SQL = "ALTER TABLE [results] ADD COLUMN [" & fld.Name & "_result] TEXT(25)"
db.Execute SQL
SQL = "UPDATE [results] SET r.[" & fld.Name & "_result] = n.[Result] " &
"FROM [results] r, [newtable] n " &
"WHERE r.[primary_key] = n.[primary_key]"
db.Execute SQL
So, if you had your [newtable] at its first two iterations like
[primary_key] [Results] [primary_key] [Results]
1 A 1 D
2 B 2 E
3 C 3 F
Your [results] table (after the above two iterations) would look like
[primary_key] [fld1_result] [fld2_result]
1 A D
2 B E
3 C F
I have a query in my Access database and a table with absolutely the same structure in another Access database.
I'm need to write a script which adds all entries from the query to the table. How can I do this?
The difference between my task and functionality of Extarnal Data -> Export -> Access Database is that I need to add new entries and save the old, but this tool can only replace old entries to new.
Create a linked table in the source database, to the destination table.
Then, use an append query to insert the results from your query into the linked table.
Edit: You can also do this with a single SQL statement:
INSERT INTO DestinationTable (Field1, Field2)
IN "C:\path\to\file.accdb"
SELECT Field1,Field2
FROM SourceTable
But the reference says:
For improved performance and ease of use, use a linked table instead of IN.
For anyone looking to link the table in VBA...
strDbName = "C:\FolderPath\DatabaseName.mdb"
strLinkTbl = "tblNameOfTableYouWantToLink"
strNameTbl = "tblWhatYouWantToNameIt" ' This can be the actual
' table name or something different
DoCmd.TransferDatabase acLink, "Microsoft Access", strDbName, _
acTable, strLinkTbl, strNameTbl
Then your SQL looks like:
CurrentDb.Execute "INSERT INTO " & strNameTbl _
& " (Field1, Field) SELECT Field1, Field2 FROM SourceTable
Each day ~5000 records are uploaded to tblRecordsCurrent, at some point within the next few days when those records have been processed, they need to be moved to tblRecordsHistorical. Each record has a Foreign Key DataSetID that ties it to the date/time it was uploaded (Parent Table).
How, within vba, can I insert a single DataSet of tblRecordsCurrent into the tblRecordsHistorical from tblRecordsCurrent. I cannot insert all columns as both tables contain persisted columns.
I can't put the entire INSERT INTO tblRecordsHistorical A, B, C, D, E, F... as it is too long for access vba.
Any ideas?
If you save the query in your Access database, then you can execute in in VBA the following way:
DoCmd.OpenQuery "yourQueryName", acViewNormal, acEdit
Or
CurrentDb.OpenRecordset("yourQueryName")
Or
CurrentDb.Execute "qryAddLoginfoRow"
This allows you to execute the query without having the query stored in your VBA code. But you are also able to execute this via a query in VBA:
INSERT INTO tblRecordsHistorical (col1, col2...)
SELECT col1, col2...
FROM tblRecordsCurrent
EDIT:
You can create a long SQL string by concatenating the string together:
SQLString = "INSERT INTO tblRecordsHistorical (col1, col2...) " & _
" SELECT ... " & _
" FROM tblRecordsCurrent "