ExecuteNonQuery 无法创建 TempTable SQL 服务器

ExecuteNonQuery is not working to create TempTable SQL Server

没有在数据库中创建临时 table。我验证凭据有权创建临时 table。复制并粘贴 SQL 命令,它在 SSMS 中有效。

调试时没有抛出异常。 cmd 变量在执行前具有正确的连接和 SQL 文本。

我在应用程序的其他部分使用了相同的连接字符串来成功查询服务器,所以那里没有问题。

我的目标是创建一个临时文件 table,然后通过 SqlBulkCopy 填充它,然后进行合并更新,然后删除临时文件 table。

编辑:我的错误是在 DestinationTableName 中引用了错误的 table,但更重要的是,我正在使用无法看到临时 table 的单独连接检查 SSMS 中的进度。此外,finally 语句是多余的。谢谢大家!

        string tmpTable = @"create table #TempTable 
                            (
                            [Column1] [varchar](50) NOT NULL,
                            [Column2] [varchar](50) NOT NULL,
                            [Column3] [varchar](50) NOT NULL
                            )";
        string connString = "Data Source=AzureDBServer;" + 
                                "Initial Catalog=Database;" + 
                                "User id=UserId;" + 
                                "Password=Password;";

        using (SqlConnection connection = new SqlConnection(connString))
        {
            connection.Open();
            SqlCommand cmd = new SqlCommand(tmpTable, connection);
            cmd.ExecuteNonQuery();

            try
            {
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
                {
                    bulkCopy.DestinationTableName = "#TempTable";
                    bulkCopy.WriteToServer(dataTable);

                    string mergeSql = "<Will eventually have merge statement here>";

                    cmd.CommandText = mergeSql;
                    int results = cmd.ExecuteNonQuery();

                    cmd.CommandText = "DROP TABLE #TempTable";
                    cmd.ExecuteNonQuery();
                }
            }
            catch (Exception)
            {
                throw;
            }

            finally
            {
                SqlCommand final = new SqlCommand("DROP TABLE #TempTable", connection);
                final.ExecuteNonQuery();

            }

        }

I'm checking in SSMS using the same credentials, getting the "Invalid object name '#TempTable'" error after the code completes

那是因为 SSMS 使用的是 不同的连接,而 temp-tables 和 #Fooper-connection.您不能从任何其他连接访问#Footemp-table。

听起来你想要一个全局 temp-table。这就像将它命名为 ##Foo 而不是 #Foo 一样简单。全局 temp-tables 在所有连接上共享。

正如@MarcGravell 在评论中指出的那样,问题是一个简单的错字。

bulkCopy.DestinationTableName = "TempTable";

应该是

bulkCopy.DestinationTableName = "#TempTable";

Temp table 如果不是在嵌套批处理或存储过程中创建,则具有会话生命周期。

EG 这个有效:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sqlclienttest
{
    class Program
    {
        static void Main(string[] args)
        {
            string tmpTable = @"create table #TempTable 
                                (
                                [Column1] [varchar](50) NOT NULL,
                                [Column2] [varchar](50) NOT NULL,
                                [Column3] [varchar](50) NOT NULL
                                )";
            string connString = "Data Source=xxxx.database.windows.net;" +
                                    "Initial Catalog=Adventureworks;" +
                                    "User id=xxxxxx;" +
                                    "Password=xxxxxx;";

            var dataTable = new DataTable();
            dataTable.Columns.Add("Column1", typeof(string));
            dataTable.Columns.Add("Column2", typeof(string));
            dataTable.Columns.Add("Column3", typeof(string));

            dataTable.BeginLoadData();
            for (int i = 0; i < 10000; i++)
            {
                var r = dataTable.NewRow();
                r[0] = $"column1{i}";
                r[1] = $"column2{i}";
                r[2] = $"column3{i}";
                dataTable.Rows.Add(r);
            }
            dataTable.EndLoadData();

            using (SqlConnection connection = new SqlConnection(connString))
            {
                connection.Open();
                SqlCommand cmd = new SqlCommand(tmpTable, connection);
                cmd.ExecuteNonQuery();

                try
                {
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
                    {
                        bulkCopy.NotifyAfter = 1000;
                        bulkCopy.SqlRowsCopied += (s, a) => Console.WriteLine($"{a.RowsCopied} rows");
                        bulkCopy.DestinationTableName = "#TempTable";
                        bulkCopy.WriteToServer(dataTable);

                        //string mergeSql = "<Will eventually have merge statement here>";

                        //cmd.CommandText = mergeSql;
                        //int results = cmd.ExecuteNonQuery();

                        cmd.CommandText = "DROP TABLE #TempTable";
                        cmd.ExecuteNonQuery();
                    }
                }
                catch (Exception)
                {
                    throw;
                }


            }
        }
    }
}

唯一的问题是,如果客户端驱动程序决定将您的 CREATE TABLE 语句包装在 sp_executesql 或类似的语句中,临时 table 将具有嵌套的批处理生命周期,而不是会话生命周期.但是 System.Data.SqlClient 不会执行此操作,除非您将参数放入创建临时 table.

的批处理中