【问题标题】:Code Generation of an Upsert / Merge for SQL Server - C#/.NETSQL Server 的 Upsert / Merge 代码生成 - C#/.NET
【发布时间】:2014-09-16 11:58:20
【问题描述】:

为 SQL Server 生成“UPSERT”合并语句的最佳方法是什么?我正在寻找一种方法,只需放入 SQL Server 连接字符串,然后将一段代码指向单个 SQL Server 表。

是不是爬取INFORMATION_SCHEMA.COLUMNS和INFORMATION_SCHEMA.TABLES获取元数据,写一个小控制台app?其他建议?

我希望能够将生成的代码复制并粘贴到“const string sql”变量中,然后与 Dapper 之类的东西一起使用。

【问题讨论】:

  • google.com/… Stack Overflow 不适合要求找工具或网站。
  • 只是想知道除了如何解决它...如果我正在解决一个已知问题?另外,想知道是否有人已经用 T4 或 CodeSmith 解决了这个问题?
  • 是的,这是一个已知问题,您的问题很好而且很重要。只是SO不是问的好地方。这是明确禁止的,并且有充分的理由(请参阅常见问题解答和元数据)。在别处问。 (当然,这里欢迎你。只是不要问这个问题。)

标签: sql-server tsql sql-server-2012 code-generation upsert


【解决方案1】:

在 C# 中的 SQL Server 中更新插入的最快方法是批量插入临时表并从那里合并到生产表。

var tmpTable =
                "create table #myTable (a as int, b as nvarchar(200)";

var conString = "my_connection_string";

 using (var con = new SqlConnection(conString))
            {
                con.Open();

                //Create Temp Table
                var cmd = new SqlCommand(tmpTable, con);
                cmd.ExecuteNonQuery();

                //Build Data Set
                var dt = new DataTable();
                dt.Columns.Add(new DataColumn("A", typeof(int)));
                dt.Columns.Add(new DataColumn("B", typeof(string)));

                foreach (var myDataRow in myData)
                {
                    var row = dt.NewRow();

                    row["A"] = myDataRow.A;
                    row["B"] = myDataRow.B;
                    dt.Rows.Add(row);
                }

                //Write to temp table
                using (var bulk = new SqlBulkCopy(con))
                {
                    bulk.BulkCopyTimeout = 0;
                    bulk.DestinationTableName = "#myTable";
                    bulk.WriteToServer(dt);
                }

                //Do the upsert
                var mergeSql = "merge into myData as Target " +
                               "using #myTable as Source " +
                               "on " +
                               "Target.A=Source.A " +
                               "and Target.B = Source.B " +
                               "when matched then " +
                               "update set Target.A=Source.A, Target.B = Source.B, " +
                               "when not matched then " +
                               "insert (A,B) values (Source.A,Source.B);";

                cmd.CommandTimeout = 0;
                cmd.CommandText = mergeSql;
                cmd.ExecuteNonQuery();

                //Clean up the temp table
                cmd.CommandText = "drop table #myTable";
                cmd.ExecuteNonQuery();
            }
        }

我已经测试了几种方法,这是我遇到的最快的方法。我在生产环境中使用它每天插入数百万行而不会出现问题。

【讨论】:

  • 您的博客托管服务似乎已过期。您还有关于如何执行此操作的信息吗?
  • 是的,杀了它。答案是批量插入临时表。然后做一个sql合并。快得多,快 50% 以上。
  • 我更新了我的答案。由于我不再拥有该网站的链接,因此删除了该网站的链接,并直接在此处发布了答案。
猜你喜欢
  • 2011-01-29
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 2019-06-22
  • 1970-01-01
  • 2011-01-02
相关资源
最近更新 更多