Reputation: 509
I am trying to figure out how to download using an ADO/DAO connection in Access VBA to get the contents of a table from SQL server. I am trying to avoid using a linked table because the DB requires a password and I keep running into issues with getting it to not ask for the login info. Are there any ideas or references for me to start with on this matter?
Upvotes: 0
Views: 2820
Reputation: 48964
Use of a linked table does not require you store or have the user password in that linked table.
If you execute a SINGLE logon at application startup then all linked tables will work.
Linked tables work WITHOUT a prompt for user or password.
Linked tables work WITHOUT you having to store the user ID or password in the link.
Access will cache the user name + password if you logon as per the instructions here:
So to download a table to a local, then you ONLY need this code:
For a new local table (create table query):
CurrentDb.Execute "SELECT * INTO LocalTableCreate FROM ServerTable"
Append to existing table:
CurrentDb.Execute "INSERT INTO LocalTable SELECT * FROM ServerTable"
And if some really strange reason and desire exists create and promote world poverty and do things the hard way like a turtle with time to waste and not use a linked table?
Well you could create a linked table via the “transfer database” command. It is only one extra line of code in front of the above code and then AGAIN the above two examples would work fine.
However I see little if any advantage to creating + deleting a linked table.
I suppose for reasons of performance or perhaps for security or the legitimate reason of you not knowing the table ahead of time? Then I would suggest you use a saved a pass-though query as performance will be even faster.
So you can use this code:
Dim qdfPass As DAO.QueryDef
Set qdfPass = CurrentDb.QueryDefs("MyPass")
qdfPass.SQL = "select * from dbo.MyTable;"
CurrentDb.Execute "INSERT INTO LocalTable SELECT * FROM MyPass”
Note that the sql used in above qerydef MUST be native T-SQL and can be a view or even a store procedure like:
qdfPass.SQL = "exec sp_myCoolStoreProc;"
And the stored procedure can even be passed a parameter like this:
qdfPass.SQL = "exec sp_myCoolStoreProc " & strMyParam
and then :
CurrentDb.Execute "INSERT INTO LocalTable SELECT * FROM MyPass”
So we can even use a select into/append from a store procedure by doing the above and the table/sql server side is dynamic or can even be a stored procedure. Again VERY little code.
I would suggest you avoid the idea proposed here to write recordset looping code unless one really has the desire to write looping code when none is required. And things like PK would have to be dealt with separate in code if you use such loops since the local pk column may need to be skipped (you simply leave that column out of the select SQL).
Note again that the connection string saved for the pass-though query does NOT require the user ID and password by using the above link showing how to “logon” to SQL Server. And if the table is known, then again a saved table link or pass-though query will suffice here.
Upvotes: 1
Reputation: 2451
It appears either way you'll need to provide SQL credentials.
There's more involved without linking a table, basically you'd want a recordset for the source and the "target" table to iterate over.
targetrs = CurrentDb.OpenRecordset("Target", dbOpenTable)
Dim Con As New ADODB.Connection
Dim sqlStr As String
Con.Open _
"Provider = sqloledb;" & _
"Data Source=SqlServer;" & _
"Initial Catalog=MyDB;" & _
"User ID=sa;" & _
"Password=p@ssW0rd;"
Dim rsSource As New ADODB.Recordset
rsSource.Open "select * from SOURCE", Con
do until rsSource.eof
targetrs.addnew
for each field in rsSource
targetrs.fields(field.Name) = rsSource.fields(field.Name)
next
targetrs.update
rssource.movenext
loop
Since you still have to have the credentials, you could dynamically link the table instead:
docmd.TransferDatabase acLink,"ODBC Database",
"ODBC;Driver={SQL Server};Server=MySQLServer;Database=MYSQLDB;
Uid=USER;Pwd=PASSWORD",acTable,"SQLtable","MyAccessTable"
Upvotes: 2