Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Copying records from access to SQL

Status
Not open for further replies.

llefebure

MIS
Jan 17, 2002
27
0
0
US
Greetings everyone. I was recently looking to find a way to copy a bunch of records from an access database up to a SQL server. I couldn't find much, so I created this script. It is the fastest way of copying records that I could find. My goals were to make sure the records get there, no duplicates, and speed across both a LAN an a WAN. This script was able to copy about 60 records a second from access to SQL with all services on 1 PC (600MHz). It was almost that fast across a 100M LAN.

In both access and SQL, there is a table named "activity". There is a field called "tkey" in both tables. There is the addition of a localtkey field in the SQL database. That field is local to the client running access. This is to help tell if the record is already in SQL or not.

I case you are wondering what this code is for, it is an application that talks to a SQL server if it can. If the server or network goes down, the client can continue to record new records. when the link to SQL comes back up, this script can be run to sync the data to SQL.

Here is what this script does:
-Gets the first 10 non-uploaded records from Access.
-Writes these records to SQL
-Marks them as uploaded in Access.


Sample code:
-------------------
Code:
Dim nodata
Dim dblocation
Dim sqldc,sqlrs
Dim accessdc,accessrs
Dim cmdsqlread,cmdsqlwrite,cmdsqlstring
Dim cmdaccessread,cmdaccesswrite
Dim recordquantity,tkeyarray
Dim keepgoing,i,recordsuploaded
Dim POS,tkey,tdate,ttime,Price
dblocation = "C:\Inetpub\[URL unfurl="true"]wwwroot\testsql\speed.mdb"[/URL]
recordquantity = 10

'Open connections to SQL and Access
Set accessdc = Server.CreateObject("ADODB.Connection")
accessdc.Open = "DRIVER={Microsoft Access Driver (*.mdb)};dbq=" & dblocation & ";"
Set sqldc = Server.CreateObject("ADODB.Connection")
sqldc.Open "Driver={SQL Server};Server=127.0.0.1;Database=speedtest;UID=sa;PWD="

Response.Write(&quot;<HTML><HEAD><TITLE>SQL Speed Test</TITLE></HEAD>&quot;)
Response.Write(&quot;<BODY>&quot;)

'Delete all records from the SQL activity table
cmdsqlwrite = &quot;DELETE FROM activity&quot;
Set sqlrs = Server.CreateObject(&quot;ADODB.Recordset&quot;)
sqlrs.Open cmdsqlwrite, sqldc

'Set some records to be uploaded (total is x-1)
cmdaccesswrite = &quot;UPDATE activity SET processed = 0 WHERE tkey < 9951&quot;
Set accessrs = Server.CreateObject(&quot;ADODB.Recordset&quot;)
accessrs.Open cmdaccesswrite, accessdc


Response.Write(&quot;We are now going to copy all local unprocessed records to the main database.<BR><BR>&quot;)
Response.Write(&quot;<BR>Started<BR>&quot;)

'------------------------------------------------

keepgoing = 1	'This is so it runs until all records are done.
recordsuploaded = 0
cmdaccessread = &quot;SELECT TOP &quot; & recordquantity & &quot; * FROM activity WHERE processed = 0&quot;

Do Until keepgoing = 0
	'Pull the first record(s) that needs to be updated.
	Set accessrs = Server.CreateObject(&quot;ADODB.Recordset&quot;)
	accessrs.Open cmdaccessread, accessdc
	If accessrs.EOF Then
		accessrs.Close
		'We're all done with the updates. No more stuff to do.
		keepgoing = 0
	Else
		'There is at least 1 record to work with.
		tkeyarray = nodata
		cmdsqlstring = nodata
		cmdsqlstring = &quot;BEGIN TRANSACTION &quot;

		Do Until accessrs.EOF
			'Read in the data
			POS = accessrs(&quot;POS&quot;)
			tkey = accessrs(&quot;tkey&quot;)
			tdate = DateValue(accessrs(&quot;tdate&quot;))
			ttime = TimeValue(accessrs(&quot;ttime&quot;))
			Price = accessrs(&quot;Price&quot;)
			cmdsqlread = &quot;SELECT * FROM activity WHERE (POS = '&quot; & POS & &quot;' AND localtkey = '&quot; & tkey & &quot;' AND tdate = '&quot; & tdate & &quot;')&quot;
			cmdsqlwrite = &quot;INSERT INTO activity (tkey,localtkey,ID,code,Product,Price,tdate,ttime,FID,status,remarks,method,POS,meal) VALUES ('0', '&quot; & tkey & &quot;', '&quot; & accessrs(&quot;ID&quot;) & &quot;', '&quot; & accessrs(&quot;code&quot;) & &quot;', '&quot; & accessrs(&quot;Product&quot;) & &quot;', '&quot; & Price & &quot;', '&quot; & tdate & &quot;', '&quot; & ttime & &quot;', '&quot; & accessrs(&quot;FID&quot;) & &quot;', '&quot; & accessrs(&quot;status&quot;) & &quot;', '&quot; & accessrs(&quot;remarks&quot;) & &quot;', '&quot; & accessrs(&quot;method&quot;) & &quot;', '&quot; & POS & &quot;', '&quot; & accessrs(&quot;meal&quot;) & &quot;')&quot;
			cmdsqlstring = cmdsqlstring & &quot;IF NOT EXISTS(&quot; & cmdsqlread & &quot;) &quot;
			cmdsqlstring = cmdsqlstring & &quot;BEGIN &quot;
			cmdsqlstring = cmdsqlstring & cmdsqlwrite & &quot; &quot;
			cmdsqlstring = cmdsqlstring & &quot;END &quot;
			tkeyarray = tkeyarray & tkey & &quot;,&quot;
			i = i + 1
			accessrs.MoveNext
		Loop
		accessrs.Close
		cmdsqlstring = cmdsqlstring & &quot;COMMIT TRANSACTION&quot;

		'Write the data to SQL
		Set sqlrs = Server.CreateObject(&quot;ADODB.Recordset&quot;)
		sqlrs.Open cmdsqlstring, sqldc

		'Write as uploaded in access
		tkeyarray = Left(tkeyarray, Len(tkeyarray)-1)
		tkeyarray = Split(tkeyarray, &quot;,&quot;)
		For i = LBound(tkeyarray) To UBound(tkeyarray)
			cmdaccesswrite = &quot;UPDATE activity SET processed = 1 WHERE (tkey = &quot; & tkeyarray(i) & &quot;) &quot;
			Set accessrs = Server.CreateObject(&quot;ADODB.Recordset&quot;)
			accessrs.Open cmdaccesswrite, accessdc
			recordsuploaded = recordsuploaded + 1
		Next

		Response.flush
	End If
Loop
If recordsuploaded = 0 Then
	Response.Write(&quot;<BR>There were no records to write to SQL. Synchronization complete.&quot;)
End If

'------------------------------------------------

Response.Write(&quot;<BR>Stopped<BR>&quot;)
Response.Write(&quot;Records Uploaded = &quot; & recordsuploaded & &quot;<BR>&quot;)
Response.Write(&quot;</BODY></HTML>&quot;)
Response.End

'Close the connections to SQL and Access
accessdc.Close
Set accessrs = Nothing
Set accessdc = Nothing
sqldc.Close
Set sqlrs = Nothing
Set sqldc = Nothing
 
Pretty :)
Now write as a service on the backup machine so that it will auto-check the SQL Server machine and when it comes back up, automatically resynch without anyone coming to help :)
-Tarwn
 
Nice thought. I would like to do that. Assume SQL goes down, the client PC has a couple thousand records created. SQL comes back up. This &quot;background service&quot; sees that SQL is back up and begins pulling all this data out of the access database to dump into SQL. The problem is that this background service will have the access database locked and the user will not be able to read or write any records to it.

The more I learn about SQL, the less I like Access.
 
Access is the devil. Not consistent with std SQL, bad for maintenance, small storage space, WAY to many reserved words without any kind of warning when you unwittingly try to use one, i could go for ages...

If the SQL server is back up then the user shouldn't be touching the access db anymore, only the SQL server one. If it is a web service just post a message that primary data storage is down so service might be a little slow, when it comes back up post a message that primary data service came back online within last 5 minutes, retrieval might be a little slow, the rest of the time list as all servers good to go.

-Tarwn
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top