15

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

临时表应该持续整个会话,所以当参数添加到命令对象时,我看不出有什么关系。

失败:

        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

        }

作品:

        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(或相关)代码中的错误,但因为我现在有了解释,我可以继续前进。

4

2 回答 2

11

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

于 2014-04-23T07:47:56.337 回答
0

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

于 2012-07-31T17:57:15.017 回答