Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net SqlBulkCopy是如何工作的_.net_Sql Server_Sqlbulkcopy - Fatal编程技术网

.net SqlBulkCopy是如何工作的

.net SqlBulkCopy是如何工作的,.net,sql-server,sqlbulkcopy,.net,Sql Server,Sqlbulkcopy,我熟悉C#SqlBulkCopy类,在该类中,可以通过数据表调用“WriteToServer”方法 我的问题是,SQL server中的哪种底层机制用于批量插入该数据 我询问的原因是MSDN T-SQL帮助文件中引用的大容量插入需要导入数据文件。SqlBulkCopy是否创建数据文件 我想了解这些内容,以确定是否可以在SQL中使用大容量插入功能 如果我编写了一个SQL语句,准备将所有行插入到一个特定的表中(数千行),那么我可以将它们批量插入到目标表中吗?我现在就是这样做的 INSERT INTO

我熟悉C#SqlBulkCopy类,在该类中,可以通过数据表调用“WriteToServer”方法

我的问题是,SQL server中的哪种底层机制用于批量插入该数据

我询问的原因是MSDN T-SQL帮助文件中引用的大容量插入需要导入数据文件。SqlBulkCopy是否创建数据文件

我想了解这些内容,以确定是否可以在SQL中使用大容量插入功能

如果我编写了一个SQL语句,准备将所有行插入到一个特定的表中(数千行),那么我可以将它们批量插入到目标表中吗?我现在就是这样做的

INSERT INTO sync_filters (table_name, device_id, road_id, contract_id)
    SELECT * FROM dbo.sync_contract_filters (@device_id)

dbo.sync_contract_过滤器是生成要插入的所有行的函数。可以批量插入吗?

SqlBulkCopy不创建数据文件。它使用可用的通信协议(命名管道、TCP/IP等)将数据表直接从.Net DataTable对象流到服务器,并使用BCP使用的相同技术将数据批量插入目标表。

SqlBulkCopy可以使用DataTable、IDataReader或DataRow[]作为数据源。看看这个类的WriteToServer方法。我发现它是将数据导入SQL Server的一种非常有用的机制。我以前曾结合使用过这个。上一个链接让您了解了它如何与实现IDataReader的类一起工作

您可能需要确保获得预期的性能


如果您希望从快速写入大量数据中获得最佳性能,那么MSDN是一个非常有用的资源。它更多地关注BCP和大容量插入之类的内容,但涉及到SQLBulkCopy,也提供了很多值得思考的东西(可能有点太多,但至少是一个有用的参考)。

花了7年时间,但我们终于找到了答案

在解释Sam Anwar的答案时,我可以确认它正在将数据转换为原始字节流并将其写入SQL,就好像它是从文件流进来的一样。我无法理解它是如何欺骗SQL使其认为它正在读取文件的

我想从查询内部进行批量插入,以加快缓慢的聚集索引插入。在这里找到你的帖子后,不知怎的,我变得非常好奇,所以我花了几个小时研究它

实际将数据写入服务器的执行路径似乎是:

您的代码:

  • 您的代码调用System.Data.SqlClient.SqlBulkCopy.WriteToServer()
  • 在System.Data.SqlClient.SqlBulkCopy内部:

  • 哪个叫()
  • 它调用()来映射列,调用()来写入数据
  • 哪个叫()
  • 哪个调用()(这是答案。请跳到步骤14阅读。)和()
  • 哪个(CopyBatchesAsync)调用()
  • --内部System.Data.SqlClient.TdsParser:

  • 调用System.Data.SqlClient.TdsParser.()
  • 哪个调用()或类似方法将数据转换为字节数组
  • 哪个叫()
  • 哪个叫()
  • 哪个叫()
  • 哪个叫()
  • --在System.Data.SqlClient.SnNativeMethodWrapper内部:

  • 哪个叫()
  • 哪个外部程序调用()或()
  • 现在这里是它变得棘手的地方。我想这就是原因,但我是如何到达那里的有点不太清楚。我打开了sni.dll副本上的文件属性,转到“详细信息”选项卡,在产品版本属性中找到了对d0d5c7b49271cadb6d97de26d8e623e98abdc8db“提交哈希”的引用

    所以我,通过我发现,它的标题包括“System.Data.SqlClient.sni”,这意味着名称空间System.Data.SqlClient.sni,我发现了它,但它没有正确的方法,实际上似乎没有与服务器通信

    因此,这就是我耗尽知识的地方;这是我在进入本机代码之前所能达到的深度,我在任何地方都找不到。虽然我不确定上面的其他噪音是什么

  • 还记得步骤4(())也调用()
  • 它在名为updateBulkCommandText的StringBuilder中连接SQL查询。最后一个链接中的第544行
  • TLDR:最终看来,它只是执行一个查询(不需要文件),而不是实际使用(需要文件)。请注意,这两个命令看起来非常相似

    Microsoft文档中的一个重要注意事项:

    由外部工具用于上载二进制数据流。这个选项是 不适用于SQL Server Management Studio等工具, SQLCMD、OSQL或数据访问应用程序编程接口,如 作为SQL Server本机客户端


    我将其解释为“使用时自担风险,不要期望得到帮助”。公平地说,这几乎和绿灯一样好。

    另外,我感兴趣的是,我可以创建一个SQL语句,为特定表创建我需要的行,然后批量插入它们(这完全是使用SQL)。例如,BCP可以这样做吗?我觉得bcp也使用表格,这让我很感兴趣。知道datatable结构如何与包装器中的ODBC连接交互吗?我想构建类似C++的东西。或者你知道C++库有一个Simular弹出拷贝函数吗?也许可以使用对BCP的system()调用来实现这一点,并避免任何与ODBC API交互的自定义编程?确实有些有趣的链接,谢谢。这是另一个有趣的链接;rando尽最大努力记录原始TDS格式。