I have an ODBC connection to SQL Server. I need to process data within Access, but it takes too long. My idea is to push this data to a SQL Server temp table and have SQL Server
Here is a snippet of VBA code I used to call a DB2 stored procedure. The same technique should work for any DDL statement. To do this, create a pass-through query and put your CREATE TABLE #tblname...
statement as its SQL text.
IMPORTANT: Then open the query's property sheet and set the 'Returns Records' property to "No".
Dim qdf As QueryDef
Set qdf = CurrentDb.QueryDefs("qry_SP_CHANGE_COLUMN")
qdf.Connect = CurrentDb.TableDefs("SCHEMA_tblName").Connect
qdf.SQL = "call SCHEMA.SP_CHANGE_COLUMN(...)"
qdf.Execute dbFailOnError
qdf.Close
Set qdf = Nothing
Note, you probably won't have to change your SQL text. You can just leave that in the query def if the table structure never changes.
The challenge for you is that you must use the same connection for any operations against the temp table. The minute the connection is closed, your temp table will vanish because it's a local temp table, and it's only visible to that one connection. You can avoid this by using '##', global temp tables, if you have rights to do that.
Brian is correct that you could use a Pass-Through query to create a temporary table in the SQL Server database. I confirmed this by creating the following four pass-through queries in Access:
[ptq1 create temp table]
BEGIN TRY
DROP TABLE #tblname
END TRY
BEGIN CATCH
-- do nothing
END CATCH
CREATE TABLE #tblname (intInput int, intResult int);
[ptq2 populate temp table]
INSERT INTO #tblname (intInput) VALUES (1)
[ptq3 do calculations]
UPDATE #tblname SET intResult=intInput*2
[ptq4 retrieve results]
SELECT * FROM #tblname
I can run each of these in succession by double-clicking them in Access' list of saved queries, and the final query returns
intInput IntResult
-------- ---------
1 2
The stumbling block here looks like it will be how to get the data from the local Access table into the temporary table. In VBA I tried both
DoCmd.TransferDatabase acLink, "ODBC Database", "ODBC;DSN=myDB", acTable, "#tblname", "sqlTemp"
and
Set tbd = cdb.CreateTableDef("sqlTemp")
tbd.Connect = "ODBC;DSN=myDb;Trusted_Connection=Yes;APP=Microsoft Office 2010;DATABASE=myDb;"
tbd.SourceTableName = "#tblname"
cdb.TableDefs.Append tbd
and both methods failed because they could not "see" the temporary table. (The exact same code worked when I tried to create a link to a "real" table in that same SQL Server database.) I also tried using tbd.OpenRecordset
to create a recordset without appending the TableDef to the TableDefs collection and that failed, too.
Without a link to the temporary table it seems that populating it could be problematic. I suppose one could use code like...
Set rst = cdb.OpenRecordset("localTable", dbOpenSnapshot)
Do While Not rst.EOF
Set qdf = cdb.CreateQueryDef("", "INSERT INTO [#tblname] (intInput) VALUES (" & rst!intInput & ")")
qdf.Connect = "ODBC;DSN=myDb;Trusted_Connection=Yes;DATABASE=myDb;"
qdf.ReturnsRecords = False
qdf.Execute dbFailOnError
Set qdf = Nothing
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
... to transfer the data from the local table to the temporary table row-by-row, but that could get pretty tedious for a large number of columns, and it could be rather slow for a large number of rows.
So if I was in your position I would try to make my case for having a "real" table created in the SQL Server database. It certainly would make things a lot simpler.