PRB: SQL Server Local Temp Tables Aren't Created When Parameterized ADO Query Is Used (295743)



The information in this article applies to:

  • ActiveX Data Objects (ADO) 2.0, when used with:
    • Microsoft SQL Server 2000 (all editions)
    • Microsoft SQL Server, Standard Edition 7.0
    • Microsoft SQL Server, Enterprise Edition 7.0
  • ActiveX Data Objects (ADO) 2.1, when used with:
    • Microsoft SQL Server 2000 (all editions)
    • Microsoft SQL Server, Standard Edition 7.0
    • Microsoft SQL Server, Enterprise Edition 7.0
  • ActiveX Data Objects (ADO) 2.5, when used with:
    • Microsoft SQL Server 2000 (all editions)
    • Microsoft SQL Server, Standard Edition 7.0
    • Microsoft SQL Server, Enterprise Edition 7.0
  • ActiveX Data Objects (ADO) 2.6, when used with:
    • Microsoft SQL Server 2000 (all editions)
    • Microsoft SQL Server, Standard Edition 7.0
    • Microsoft SQL Server, Enterprise Edition 7.0
  • Microsoft OLE DB Provider for SQL Server 7.0
  • Microsoft OLE DB Provider for SQL Server 7.01
  • Microsoft ODBC Driver for SQL Server 2000.80.194
  • Microsoft ODBC Driver for SQL Server 3.6
  • Microsoft ODBC Driver for SQL Server 3.7
  • Microsoft OLE DB Provider for ODBC 1.0
  • Microsoft OLE DB Provider for ODBC 1.1
  • Microsoft OLE DB Provider for ODBC 1.5
  • Microsoft OLE DB Provider for ODBC 2.0

This article was previously published under Q295743

SYMPTOMS

When you run a query against a temporary table created by a parameterized ActiveX Data Objects (ADO) query, the following error may result:
Error -2147217865 "Invalid Object name '#<table name>'

This problem occurs with both the Microsoft OLEDB Provider for SQL Server (SQLOLEDB) and the Microsoft OLEDB Provider for ODBC Driver (MSDASQL) with the SQL Server driver.

CAUSE

ADO is designed to provide high performance with parameterized queries. The architecture it uses, however, prevents temporary tables that are created within a parameterized query from persisting outside of that query.

RESOLUTION

Several workarounds are presented in the "More Information" section of this article.

STATUS

This behavior is by design.

MORE INFORMATION

The following Microsoft Visual Basic code demonstrates the problem:

Note You must change the User ID <username> value and the Password =<strong password> value to the correct values before you run this code. Make sure that User ID has the appropriate permissions to perform this operation on the database.
Dim cn As New ADODB.Connection
Dim Cmd As New ADODB.Command
Dim Rs As New ADODB.Recordset

cn.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=<user name>; Password=<strong password>;Initial Catalog=pubs;Data Source=<INSERT YOUR SERVER NAME HERE!>"

cn.Execute "SET NOCOUNT ON"
Cmd.CommandType = adCmdText
Cmd.Parameters.Append Cmd.CreateParameter("Par", adVarChar, adParamInput, 2, "CA")
Cmd.CommandText = "SELECT au_id INTO #Pattern FROM authors where state = ? "
Set Cmd.ActiveConnection = cn

Cmd.Execute

Cmd.CommandText = "select count(*) from #Pattern"
Rs.Open Cmd, , adOpenStatic, adLockOptimistic      ' This line generates error.
MsgBox Rs.Fields(0).Value

Rs.Close
cn.Close
Set cn = Nothing
				
To work around the problem, you can do the following things:
  1. Use a nonparameterized query to create the temporary table, such as the following:
    SELECT au_id INTO #Pattern FROM authors WHERE state = 'CA'
    					
  2. Use the temporary table in the same batch in which the table is created; for example:
    Dim cn As New ADODB.Connection
    Dim Cmd As New ADODB.Command
    Dim Rs As New ADODB.Recordset
    
    cn.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=<user name>; Password=<strong password>; Initial Catalog=pubs;Data Source=reidwpri"
    
    cn.Execute "SET NOCOUNT ON"
    Cmd.CommandType = adCmdText
    Cmd.Parameters.Append Cmd.CreateParameter("Par", adVarChar, adParamInput, 2, "CA")
    Cmd.CommandText = "SELECT au_id INTO #Pattern FROM authors where state = ? " & _
        "select count(*) from #Pattern"
    Set Cmd.ActiveConnection = cn
    
    Rs.Open Cmd, , adOpenStatic, adLockOptimistic      ' This line generates error.
    MsgBox Rs.Fields(0).Value
    
    Rs.Close
    cn.Close
    Set cn = Nothing
    					
  3. Use global temporary tables instead of local temporary tables:
    Dim cn As New ADODB.Connection
    Dim Cmd As New ADODB.Command
    Dim Rs As New ADODB.Recordset
    
    cn.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=<user name>;Password=<strong password>;Initial Catalog=pubs;Data Source=reidwpri"
    
    cn.Execute "SET NOCOUNT ON"
    Cmd.CommandType = adCmdText
    Cmd.Parameters.Append Cmd.CreateParameter("Par", adVarChar, adParamInput, 2, "CA")
    Cmd.CommandText = "SELECT au_id INTO ##Pattern FROM authors where state = ? "
    Set Cmd.ActiveConnection = cn
    Cmd.Execute
    
    Cmd.CommandText = "SELECT count(*) from ##Pattern"
    Rs.Open Cmd, , adOpenStatic, adLockOptimistic      ' This line generates error.
    MsgBox Rs.Fields(0).Value
    
    Rs.Close
    cn.Close
    Set cn = Nothing
    					

Modification Type:MajorLast Reviewed:10/31/2003
Keywords:kbprb KB295743 kbAudDeveloper