8

我正在编写一个将数据写入 SQL Server 2008r2 的 .NET 应用程序。我有两个插入数据的选项,我可以创建一个大字符串插入语句,并将其作为文本命令发送,或者我可以在 .NET DataTable 中收集数据,并将其作为表值参数传递。每种方法的好处和成本是什么?

(我省略了很多代码,因为我只是询问相对的好处,而不是具体的语法)

例如:

选项1:

    string insert = @"insert into MyTable (id, val) values
        ( 1, 'a'),(2,'b'),(3,'c'),(4,'d');"

选项 2:

    DataTable dt = new DataTable();
    dt.Columns.Add("id", typeof(int));
    dt.Columns.Add("val", typeof(string));
    ....
    create procedure uspMyProc 
                    @tt ttMyTableType readonly
                as
                begin
                    insert into TestTable1 (id, strValue)
                    select myId, myVal from @tt;
                end"

谢谢你的帮助。

4

3 回答 3

7

选项 3:在第一个实例中,我将使用一个插入语句的参数值填充插入存储过程,并在 C# 代码的循环中多次调用它:

选项 4:如果您确实有很多行要插入,也许您需要查看SqlBulkCopy 类。它消耗DataTable或。您可以使用一些自定义代码从对象列表中创建一个,这里提出了一个类似的问题:DataRowIDataReaderIDataReader

从类型化列表中获取 IDataReader


我会说这取决于。

如果您真的想以表格形式传递多行参数,无论出于何种原因,请使用表值参数 - 这就是它的用途。

我已经看到了选项 1 - 一些通用 DAL 代码将编写一个 SQL“批处理”命令来运行。它有效,但没有对注入攻击提供任何防御。参数化的 SQL 可以。


话虽如此,我更愿意为要从代码中插入的每一行调用一次插入存储过程——调用将完全参数化并且性能很好。如果性能成为问题,我会支持选项 4。

于 2012-05-25T15:29:16.233 回答
5

大有多大?如果它很大,没有什么比 SqlBulkCopy 更好的了。实际上,我发现 TVP 的表现令人失望。对于查询计划的重用,我是参数化和大规模重用语句的粉丝。Dapper 可以帮助解决这个问题,允许您将对象列表传递给查询 - 然后它将按成员名称添加每个对象的命名参数,每秒执行数千次操作。例如:

conn.Execute(
    "insert foo (Id,Name) values (@Id,@Name)",
    listOfObjects);

这将迭代列表并使用.Id.Name从每个对象依次执行查询。

于 2012-05-25T15:36:05.737 回答
4

值限制为 1000

并且值似乎有一些性能问题

插入具有多个值的性能问题

我使用 TVP 插入数千行,它对我很有用。我使用 List 集合作为 TVP 源,因为 DataTable 有更多开销。如果可以,插入按 PK 排序的行。

话虽如此,我将尝试 Marc Gravell 的答案。

JNK 对 TVP 普遍不信任。

于 2012-05-25T15:42:33.527 回答