我需要创建一个桌面应用程序,以将数据从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,因此不会使用太多本地内存
答案 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)