Reputation: 1873
Situation: We receive statistical source data on monthly basis. It comes as a CD with an Access database which contains two tables. So we have 1 *.mdb file with 2 tables inside. Analysts should be able to import data, calculate and standardize it and check results. If results are fine data is populated. Analysts are not programmers and they don't have SQLServerManagementStudio.
My task: To create an access form as front-end for analysts with buttons: import, calculate, check, populate. Every button will fire the path trough query which run't stored procedure on sql server's side.
My problem: The bottleneck of my project is data import. It should be done automatically(NOT manually as analysts don't have management studio installed).
What I tried:
1) I linked SQL server's tables into access and tried to use regular queries to copy(INSERT INTO ** FROM *) but It takes too long. ( I have about 4 million rows in two tables)
2) As I fond out BULK INSERT is not working with importing from access file.
3) OPENROWSET approach:
SELECT *
FROM OPENROWSET( 'Microsoft.Jet.OLEDB.4.0','\\euro-dc\DOTS\2014\dots.mdb';'admin';'',TimeSeries)
Which returns me the error:
Msg 7308, Level 16, State 1, Line 1 OLE DB provider 'Microsoft.Jet.OLEDB.4.0' cannot be used for distributed queries because the provider is configured to run in single-threaded apartment mode.
Openrowset solution is not preferable. I would like to avoid it. Because it will will work on some computers and won't on other ones because of OLDB driver. After windows re-installation will need to check OLEDB driver ... it is not very comfortable as there are 15 analysts. Only if there is no other way to import data.
\euro-dc\dots folder is accessible for sql server - it is tested in my other project.
Will appreciate any fresh ideas. thanks
Upvotes: 3
Views: 9659
Reputation: 2016
Since you are dealing with a large number of records, you should consider the effect that indexes might be having on the performance of your data export/import process. A technique that some people use to speed things up in your situation is to first export the source data to a convenient intermediate file format (CSV or whatever), drop the indexes on the destination table, do a BULK INSERT to pull the intermediate file data into your destination table, then finally recreate the indexes on the destination table after the BULK INSERT completes.
This can help performance significantly, because recreating the indexes at the end (one time) is often much faster than the sum of all the index updates that occur when you insert rows one at a time.
I believe you should be able to programatically implement each of the steps above using VBA and T-SQL pass-through queries with Access.
Hope it helps. Good luck with your project.
Upvotes: 2
Reputation: 91356
If you use something on the lines of the query below, it will run from MS Access. You also have the option of a pass-through query, or better yet, a little code to provide parameters.
INSERT INTO
[ODBC;DRIVER=SQL Server;Server=servername;Database=dbname;Integrated Security=SSPI].Table1
SELECT * FROM Table1
The easiest way to get the correct connection string is to link the table and then check the connect property.
You will also find connections strings at http://connectionstrings.com
Some examples, note that while names are used as a reference, it is really the order of the parameters that matters. For the most part, I check if I have a connection, to save time.
A query in MS Access
Set db = CurrentDb
sSQL = "INSERT INTO dbo_LocationLocationType (LocationID,LocationTypeID) VALUES (@LocationId,@LocationName)"
Set qdf = db.CreateQueryDef("", sSQL)
qdf.Parameters![@LocationId] = LocationID
qdf.Parameters![@LocationName] = LocationName
qdf.ReturnsRecords = False
qdf.Execute dbFailOnError
A stored procedure
Dim cmd As New ADODB.Command
Dim prm As ADODB.Parameter
With cmd
.ActiveConnection = "insert connection string"
.CommandType = adCmdStoredProc
.CommandText = "NameofStoredProcedure"
Set prm = .CreateParameter("@LocationID", adInteger, adParamInput)
prm.Value = frm.txtLocationID
.Parameters.Append prm
Set prm = .CreateParameter("@LocationName", adVarWChar, adParamInput, 255)
prm.Value = frm.txtLocationDetailName
.Parameters.Append prm
.Execute
End With
Upvotes: 1
Reputation: 31
Use the import wizard and save the import specifications for each group of data you want to import. Then write some code/macro under a button that executes the import specifications. The tables you import into can be built in Access, then upsized to SQL Svr.
4 million recs is going to be slow, so you may want to put it in a separate MDB so that it doesn't tie up your analyst's working MDB.
Upvotes: 2