【问题标题】:Creating and populating temp table in different commands在不同的命令中创建和填充临时表
【发布时间】:2020-04-30 18:40:24
【问题描述】:

我遇到了一个问题,我在一个 SqlCommand 中创建了一个临时表 #muMapping,然后用另一个 SqlCommand 填充它。第二条命令在cmd.ExecutNonQuery() 上抛出异常,消息如下:

Invalid object name '#muMapping'.
Statement(s) could not be prepared.

两个命令使用相同的SqlConnection,我开始并指定要使用的事务,以便SqlCommand 不会隐式开始并提交事务。

代码:

using (var conn = new SqlConnection(connString))
{
    await OpenConnection(conn);
    var trans = conn.BeginTransaction();

    using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "CREATE TABLE #muMapping ( mu_id INT NOT NULL PRIMARY KEY, facility NVARCHAR(100) NOT NULL, team NVARCHAR(100) NOT NULL );";
        cmd.Transaction = trans;

        await cmd.ExecuteNonQueryAsync();
    }

    using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "INSERT INTO #muMapping VALUES (@mu, @facility, @team);";
        cmd.Parameters.Add("@mu", SqlDbType.Int);
        cmd.Parameters.Add("@facility", SqlDbType.NVarChar, 100);
        cmd.Parameters.Add("@team", SqlDbType.NVarChar, 100);
        cmd.Transaction = trans;

        cmd.Prepare();

        foreach (var mu in loadData)
        {
            try
            {
                cmd.Parameters[0].Value = mu.Mu;
                cmd.Parameters[1].Value = mu.Facility;
                cmd.Parameters[2].Value = mu.Team;
                await cmd.ExecuteNonQueryAsync(); //Error thrown here
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw e;
            }
        }
    }
    //Other statements
}

据我所知,#muMapping 表应该可以从第二个命令中看到。

【问题讨论】:

  • 你有一个 cmd.Transaction = trans 和一个 cmd.Transaction = transaction。这是转录错误还是实际上在您的代码中?
  • @antlersoft 这是一个转录错误,现已修复
  • 你想做什么?如果您只是尝试批量加载数据,您可以查看 table valued parameters

标签: c# sql-server


【解决方案1】:

来自Create Table

您可以创建本地和全局临时表。本地临时 表仅在当前会话中可见,全局临时 表对所有会话可见。临时表不能 分区。

所以,创建一个全局临时表(##table_name)

更新

忽略我之前的声明,我在 sql server 2014 上运行了你的代码(只做了很少的修改),它执行得很好!

public static void Bar()
    {

        Task.Run(async () =>
        {

            using (var conn = new SqlConnection("Server=.;Database=Test;Trusted_Connection=True;"))
            {
                await conn.OpenAsync();
                var trans = conn.BeginTransaction();

                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText =
                        "CREATE TABLE #muMapping ( mu_id INT NOT NULL PRIMARY KEY, facility NVARCHAR(100) NOT NULL, team NVARCHAR(100) NOT NULL );";
                    cmd.Transaction = trans;

                    await cmd.ExecuteNonQueryAsync();
                }

                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "INSERT INTO #muMapping VALUES (@mu, @facility, @team);";
                    cmd.Parameters.Add("@mu", SqlDbType.Int);
                    cmd.Parameters.Add("@facility", SqlDbType.NVarChar, 100);
                    cmd.Parameters.Add("@team", SqlDbType.NVarChar, 100);
                    cmd.Transaction = trans;

                    cmd.Prepare();


                    foreach (var i in new[] {1, 2, 3})
                    {
                        try
                        {
                            cmd.Parameters[0].Value = i;
                            cmd.Parameters[1].Value = "f";
                            cmd.Parameters[2].Value = "t";
                            cmd.ExecuteNonQuery(); //Error thrown here
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            throw;
                        }

                    }
                }
            }
        }).Wait();

        //Other statements
    }

看起来您可能有语法错误: Statement(s) Could Not Be Prepared. (SQL Error 37000)

【讨论】:

    【解决方案2】:
    using (SqlConnection cn = new SqlConnection(GetConnectionString()))
    {
    cn.Open();
    
    
    SqlTransaction transaction = cn.BeginTransaction();
    
    
    SqlCommand cmd = new SqlCommand("create table #temp (colX int, colY int)", cn, 
    transaction);
    cmd.ExecuteNonQuery();
    
    
    cmd = new SqlCommand("insert #temp values (10, 200)", cn, transaction);
    cmd.ExecuteNonQuery();
    
    
    cmd = new SqlCommand("select * from #temp", cn, transaction);
    DataTable table = new DataTable();
    table.Load(cmd.ExecuteReader());
    
    
    transaction.Commit();
    }
    

    【讨论】:

    • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    相关资源
    最近更新 更多