使用带参数的命令时,临时表的“无效对象名称”

时间:2012-07-31 17:46:21

标签: c# sql-server ado.net

我正在创建一个临时表,并使用相同的命令和连接用两个单独的语句填充它。但是,如果我创建在创建之前插入参数的表,则会收到“无效的对象名称”。如果我在创建后添加它,它可以正常工作。

临时表应该持续整个会话,所以当参数添加到命令对象时,我看不出它的重要性。

失败:

        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

        }

WORKS:

        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

        }

修改

SQL Profiler对此有了更多了解。

如果命令有任何参数,则底层代码发出“exec sp_executesql”。如果清除了参数,则底层代码会发出更直接的“CREATE TABLE”。在sp_executesql之后清理临时表,这解释了我在这里看到的内容。

对我来说,这将是SqlCommand(或相关)代码中的一个错误,但由于我现在有一个解释,我可以继续。

2 个答案:

答案 0 :(得分:7)

问题实际上是在" exec sp_executesql"声明。当ADO检测到sqlCommand中声明了参数时,默认使用" sp_executesql"而不是" exec"。但在这种情况下,第一个命令是创建TEMPORAL表,并且如已知的那样,临时表仅在存储过程(sp_executesql)内有效,并在退出时被删除。因此第二个INSERT语句在第一个示例代码中不再有效。在第二个中,临时表成功创建,并且insert语句正常执行。希望它有所帮助。

答案 1 :(得分:0)

我怀疑第一次执行的状态失败,因为它坚持必须使用每个参数。