ExecuteNonQuery()无法创建临时表SqlServer

时间:2014-09-11 18:57:16

标签: c# sql-server

我正在尝试从select语句创建临时表,以便我可以从临时表中获取架构信息。

我可以使用以下代码在SQL Server中实现此目的:

//This creates the temp table
SELECT location.id, location.name into #URM_TEMP_TABLE from location

//This retrieves column information from the temp table
SELECT * FROM tempdb.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME like '#U%'

如果我在c#中运行代码,那么:

using (CONN = new SqlConnection(Settings.Default.UltrapartnerDBConnectionString))
                            {
                                var commandText = ReportToDisplay.ReportQuery.ToLower().Replace("from", "into #URM_TEMP_TABLE from");

                                using (SqlCommand command = CONN.CreateCommand())
                                {
                                    //Create temp table 
                                    CONN.Open();
                                    command.CommandText = commandText;
                                    int retVal = command.ExecuteNonQuery();
                                    CONN.Close();



                                    //get column data from temp table
                                    command.CommandText = "SELECT * FROM TEMPDB.INFORMATION_SCHEMA.Columns WHERE TABLE_NAME like '#U%'";
                                    CONN.Open();

                                    using (var reader = command.ExecuteReader())
                                    {
                                        while (reader.Read())
                                        {
                                            ColumnsForReport.Add(new ListBoxCheckBoxItemModel
                                            {
                                                Name = reader["COLUMN_NAME"].ToString(),
                                                DataType = reader["DATA_TYPE"].ToString(),
                                                IsSelected = false,
                                                RVMCommandModel = this
                                            });
                                        }
                                    }

                                    CONN.Close();

                                    //drop table
                                    command.CommandText = "DROP TABLE #URM_TEMP_TABLE";
                                    CONN.Open();
                                    command.ExecuteNonQuery();
                                    CONN.Close();
                                }
                            }

一切正常,直到它到达drop语句:不能删除表'#URM_TEMP_TABLE'

因此ExecuteNonQuery返回2547 - 这是临时表应该包含在其中的行数。但是,似乎实际上并没有使用此表创建表。 ExecuteNonQuery是正确的调用方法吗?

1 个答案:

答案 0 :(得分:5)

临时表仅在当前会话的范围内,在您发布的代码中,您正在打开连接,创建临时表,关闭连接。

然后打开另一个连接(新会话)并尝试删除不在该会话范围内的表。

您需要在同一连接中删除临时表,或者可能使其成为全局临时表(##) - 尽管在这种情况下具有两个单独的连接,但全局临时表仍将超出范围。 / p>

此外,正如评论中指出的那样,您的临时表将自动清理 - 但如果您确实想要删除它们,则必须从创建它们的会话中执行此操作。

来自另一个SO线程的编辑:

Global temporary tables in SQL Server

  

全局临时表的运行方式与本地临时表非常相似;他们   在tempdb中创建并导致更少的锁定和日志记录   永久表。但是,它们对所有会话都可见,直到   创建会话超出范围(全局##临时表不是   更长时间被其他会议引用)。如果两个不同的会话   尝试上面的代码,如果第一个仍然有效,第二个将   收到以下信息:

     

服务器:消息2714,级别16,状态6,行1已经有一个对象   在数据库中命名为“## people”。

     

我还没有看到使用全局## temp的有效理由   表。如果数据需要持久化到多个用户,那么它就会产生   使用永久桌子至少对我来说更有意义。您可以   通过创建一个全局##临时表使其更加永久   一个自动启动程序,但我仍然不知道这是怎么回事   比永久桌更有利。有了永久桌子,你可以   否认权限;你不能拒绝来自全球##临时表的用户。

看起来全局临时表仍然超出范围......它们在一般的IMO中使用起来很糟糕。您可以将该表放在同一会话中或重新考虑您的解决方案吗?