I am using ADO/Visual C++ to access SQL Server database. I find it is OK to create only one temp table in the database. But if I create two temp tables and open recordset of one table, and access the other table, then I will get the following error:
Invalid object name ‘#TempTable1’
Below is my code:
#include "stdafx.h"
#include "TestTempTable.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
// The one and only application object
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
CoInitialize(NULL);
try {
_ConnectionPtr cn("ADODB.Connection");
_RecordsetPtr rs("ADODB.Recordset");
CString strSQLQuery;
ULONGLONG uIndex, uCount;
_variant_t vtFirstName;
cn->Provider = "sqloledb";
cn->Open("Data Source='(local)';Integrated Security=SSPI;", "", "", adConnectUnspecified);
// Create a test database
strSQLQuery = _T("CREATE DATABASE MyTestDB6;");
cn->Execute(_bstr_t(strSQLQuery), NULL, 0);
// Use the test database
strSQLQuery = _T("USE MyTestDB6;");
cn->Execute(_bstr_t(strSQLQuery), NULL, 0);
// Create a temp test table
strSQLQuery = _T("CREATE TABLE #TempTable1(Field1 bigint, Field2 int, Field3 smallint, Field4 tinyint, Field5 bigint, Field6 int, Field7 smallint, Field8 tinyint, Field9 float, Field10 datetime, Field11 nvarchar(20), Field12 nvarchar(40));");
if (cn->Execute(_bstr_t(strSQLQuery), NULL, 0))
{
// Initialize the total test count to 5
uCount = 5;
// Add multiple records by invoking Execute for multiple times
strSQLQuery = _T("INSERT INTO #TempTable1 VALUES(10000, 1000, 100, 10, 20000, 2000, 200, 20, 99.98, 1920/05/20, 'Hello', 'Hello, World!');");
for (uIndex = 0; uIndex < uCount; uIndex ++)
cn->Execute(_bstr_t(strSQLQuery), NULL, 0);
// Create temp test table 2
strSQLQuery = _T("CREATE TABLE #TempTable2(Field1 bigint, Field2 int, Field3 smallint, Field4 tinyint, Field5 bigint, Field6 int, Field7 smallint, Field8 tinyint, Field9 float, Field10 datetime, Field11 nvarchar(20), Field12 nvarchar(40));");
if (cn->Execute(_bstr_t(strSQLQuery), NULL, 0))
{
// Initialize the total test count to 5
uCount = 5;
// Add multiple records by invoking Execute for multiple times
strSQLQuery = _T("INSERT INTO #TempTable2 VALUES(10000, 1000, 100, 10, 20000, 2000, 200, 20, 99.98, 1920/05/20, 'Hello', 'Hello, World!');");
for (uIndex = 0; uIndex < uCount; uIndex ++)
cn->Execute(_bstr_t(strSQLQuery), NULL, 0);
// Select from temp test table2
strSQLQuery = _T("SELECT * FROM #TempTable2");
if (SUCCEEDED(rs->Open(_bstr_t(strSQLQuery), _variant_t(cn, true), adOpenDynamic, adLockOptimistic, 0)))
{
rs->MoveFirst();
while (!rs->EndOfFile)
{
// Some codes to operate on the recordset rs
...
// Add record to temp test table 1
strSQLQuery = _T("INSERT INTO #TempTable1 VALUES(10000, 1000, 100, 10, 20000, 2000, 200, 20, 99.98, 1920/05/20, 'Hello', 'Hello, World!');");
cn->Execute(_bstr_t(strSQLQuery), NULL, 0); // !!!!!!!!!!!!!!!!!!!Error occurs.
rs->MoveNext();
}
rs->Close();
}
}
}
}
catch (_com_error &e) {
printf("Description = '%s'\n", (char*) e.Description());
}
::CoUninitialize();
}
Why?
Now let me explain the reason why I need to use local temporary table:
My purpose of using temporary table is to reduce the memory consumption. If using table variable in a stored procedure, then since its data are stored in memory, it cannot implement my goal.
Also the data stored in the temporary table are confidential and I do not want any other users to be able to access the data. So a global temporary table or tempdb permanent tables are also not feasible.
Due to 1 and 2, temporary local table is the best option for my case. Since in my codes, I connect to SQL Server in the beginning and disconnect in the end, I should be in the same user of the same session. All my operations with the temp tables should be OK. Why the first several SQL statements are OK, but ONLY after I open a recordset, the SQL statement will cause error?
Thank you very much
INSERT
operations against both of them succeeded.1920/05/20
(without quotes) will be treated as an arithmetic expression (1920 divided by 5 divided by 20) rather than the date of May 20, 1920. Fordatetime
, SQL Server allows you to specify numeric expressions as offsets from1900-01-01
, so yourdatetime
values will be inserted without errors but they will probably be incorrect.