如何使用sqlbulkcopy将数据从dataReader流到SQL?

时间:2019-06-25 13:19:12

标签: vb.net

我需要创建一个桌面应用程序,以将数据从oracle数据库复制到SQL Server数据库(客户端明确希望这样做-ETL软件,DTS等全部用光了-它必须是桌面*。 exe)

由于数据运行到数百万(通常是几千万)的行中,因此我无法使用sqlbulkcopy(dataTable),因为dataTable的大小很快就会占用所有可用内存。

我正在使用sqlbulkCopy(dataReader),但它仍在消耗本地内存。

如何在不使用大量本地内存的情况下将数据从读取器流到sql表?

(跳过try-catching等,仅是核心代码):

Dim dr As OleDb.OleDbDataReader
Dim connString As String = "Provider=MSDAORA.1;User ID=X;password=X;Data Source=X;Persist Security Info=False"
Dim cnn As OleDb.OleDbConnection = New OleDb.OleDbConnection(connString)
Dim cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand("SELECT * FROM Table", cnn)

cnn.open
dr = cmd.ExecuteReader

Dim sqlCnn As SqlClient.SqlConnection = New SqlClient.SqlConnection("Server=X;Database=X;Trusted_Connection=True;Connection Timeout=60")
sqlCnn.Open()
Dim bk As SqlClient.SqlBulkCopy = New SqlClient.SqlBulkCopy(sqlCnn)
bk.DestinationTableName = "TABLE_NAME"
bk.EnableStreaming = True
bk.BatchSize = 100
bk.BulkCopyTimeout = 0

bk.WriteToServer(dr)  

在本地计算机上抛出内存不足异常,无论批处理大小如何。死前页面文件的使用率上升。 期望datareader可以流式传输到sql server,因此不会使用太多本地内存

1 个答案:

答案 0 :(得分:1)

感谢Jeroen使用Oracle本机提供程序而不是OLE的想法。

“ Oracle ODP.NET官方托管驱动程序”

数据现在可以快速流化(每秒约10,000行),并且不会过度消耗本地内存,正是我想要的。

新代码(缺少try-catch等,仅是代码):

'Oracle connection using ODP.Net Managed Driver
Dim factory As Common.DbProviderFactory = Common.DbProviderFactories.GetFactory("Oracle.DataAccess.Client")
Dim dbconn As Common.DbConnection = factory.CreateConnection()
Dim connString As String = "User ID=X;password=X;Data Source=X;"

dbconn.ConnectionString = connString
dbconn.Open()

'Retrieval of data from oracle
Dim dbcommand = factory.CreateCommand
dbcommand.Connection = dbconn
dbcommand.CommandText = "SELECT * FROM Table"

Dim dr As Common.DbDataReader
dr = dbcommand.ExecuteReader

'Stream to SQL
Dim sqlCnn As SqlClient.SqlConnection = New 
SqlClient.SqlConnection("Server=X;Database=X;Trusted_Connection=True;Connection Timeout=60")
sqlCnn.Open()
Dim bk As SqlClient.SqlBulkCopy = New SqlClient.SqlBulkCopy(sqlCnn)
bk.DestinationTableName = "TABLE_NAME"
bk.EnableStreaming = True
bk.BatchSize = 5000
bk.BulkCopyTimeout = 0

bk.WriteToServer(dr)