2012-07-31 17 views
12

Estoy creando una tabla temporal y llenándola con dos instrucciones separadas usando el mismo comando y conexión. Sin embargo, obtengo un 'Nombre de objeto inválido' si creo la tabla con el parámetro insertado antes de la creación. Si lo agrego después de la creación, funciona bien.'Nombre de objeto no válido' para la tabla temporal cuando se usa el comando con los parámetros

Se supone que la tabla temporal dura toda la sesión, por lo que no veo lo que importa cuando el parámetro se agrega al objeto de comando.

falla:

 using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TEST;Integrated Security=True;")) 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      conn.Open(); 

      cmd.Parameters.Add(new SqlParameter("@ID", 1234)); 

      cmd.CommandText = "CREATE TABLE #Test (ID INT NOT NULL PRIMARY KEY, I INT NOT NULL)"; 
      cmd.ExecuteNonQuery(); 

      cmd.CommandText = "INSERT INTO #Test VALUES (@ID, 1)"; 
      cmd.ExecuteNonQuery(); 

      ..... more code that uses the table 

     } 

funciona:

 using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TEST;Integrated Security=True;")) 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      conn.Open(); 

      cmd.CommandText = "CREATE TABLE #Test (ID INT NOT NULL PRIMARY KEY, I INT NOT NULL)"; 
      cmd.ExecuteNonQuery(); 

      cmd.Parameters.Add(new SqlParameter("@ID", 1234)); 

      cmd.CommandText = "INSERT INTO #Test VALUES (@ID, 1)"; 
      cmd.ExecuteNonQuery(); 

      ..... more code that uses the table 

     } 

de edición:

SQL arrojar más luz sobre esto.

Si el comando tiene algún parámetro, el código subyacente está emitiendo un "exec sp_executesql". Si se borran los Parámetros, el código subyacente emite una "CREAR TABLA" más directa. Las tablas temporales se limpian después de un sp_executesql, que explica lo que estoy viendo aquí.

Para mí, esto sería un error en el código SqlCommand (o relacionado) pero dado que ahora tengo una explicación, puedo seguir adelante.

+0

¿Qué mensaje de error está obteniendo – HatSoft

+0

Se está lanzando una SqlException, "Nombre de objeto inválido '# Prueba'" – mford

+0

Sí, esto es estándar ya que agrega una pequeña cantidad de protección adicional contra la inyección de SQL. Si lo necesita, puede usar un Procedimiento almacenado para hacer el trabajo o combinar los comandos en una consulta. – Trisped

Respuesta

0

Sospecho que el estado de la primera ejecución falla porque insiste en que se debe usar cada parámetro.

+0

No funciona de esa manera en ninguna otra declaración. El objeto de comando puede tener cualquier cantidad de parámetros y solo usa los que se usan en la declaración. – mford

+0

Además, la creación no está fallando. Ver editar arriba para más información. – mford

7

El problema es, de hecho, en la instrucción "exec sp_executesql". Cuando ADO detecta que hay parámetros declarados en sqlCommand, utiliza por defecto "sp_executesql" en lugar de "exec". Pero en este caso, el primer comando crea una tabla TEMPORAL y, como es sabido, las tablas temporales solo son válidas dentro de un procedimiento almacenado (sp_executesql) y se eliminan al salir. Por lo tanto, la segunda declaración INSERT ya no es válida en el primer código de ejemplo. En el segundo, la tabla temporal se crea con éxito y la instrucción de inserción se ejecuta normalmente. Espero eso ayude.

Cuestiones relacionadas