Мне нужно, чтобы вставлять данные в SQL
из файла csv
. В SQL я использую команду:
bulk insert InputTestData
from 'D:\Project\UnitTestProjct\RGTestingToolTestProject\NUnitTestProject\RGTestToolDB\InputTestData.csv'
with
( CODEPAGE ='RAW',
rowterminator='\n',
fieldterminator = '\t'
)
Вышеприведенная команда работает и вставляет данные при использовании анализатора запросов SQL, но выдает ошибку при выполнении из C#
с использованием приведенного ниже кода:
StringBuilder builder = new StringBuilder();
builder.Append("bulk insert " + objectName + " from ");
builder.Append("'" + ResourceFilePath + Path.DirectorySeparatorChar + objectPath + "'");
builder.Append(" with");
builder.Append(" (");
builder.Append(" rowterminator='\n',");
builder.Append(" fieldterminator = '\t'");
builder.Append(" )");
SqlHelper.ExecuteNonQuery(transaction, CommandType.Text, builder.ToString());
Он выдает ошибку:
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 1, column 8 (IsBaselineTest).
Запрос, сгенерированный кодом C #, также отлично работает в анализаторе запросов SQL
:
bulk insert InputTestData from 'D:\Project\UnitTestProjct\RGTestingToolTestProject\NUnitTestProject\\RGTestToolDB\InputTestData.csv' with ( rowterminator='
', fieldterminator = ' ',CODEPAGE ='RAW' )
Пожалуйста, дайте мне знать, если вам нужна структура таблиц CSV
и SQL
Пожалуйста, помогите выше.
Заранее спасибо
Я уверен, что вам нужно избежать обратной косой черты для терминаторов строк и полей, так как это похоже на то, что строка уже преобразует их в фактические символы 0x10 и 0x09. Я бы подумал, что это должно быть
builder.Append(" rowterminator='\\n',");
builder.Append(" fieldterminator = '\\t'");
Я только что завершил аналогичную задачу, используя SqlBulkCopy, как это было предложено некоторыми комментариями.
мой источник - это XML-документ, но ситуация довольно похожа.
решение, которое я разработал, - это веб-интерфейс для загрузки данных, некоторый код для размещения его в datatable, а затем вызов SqlBulkCopy для вставки во временную таблицу.
последний шаг - это запрос, который вставляет данные в итоговую таблицу обработки дубликатов и выполняет некоторую проверку.
вот какой-то код (на самом деле vb.net):
' create in memory datatable
' my choice has been to have the same datatype for all fields
Dim sapCustomer As DataTable = New DataTable("customer")
For Each SAPFieldName As String In SAPColMapping
sapCustomer.Columns.Add(New DataColumn(SAPFieldName, GetType(System.String)))
Next
' fill previous table using xml data
For Each SapRow As XmlNode In RowList.SelectNodes("ROW")
... more code here to translate xml into datatable...
Next
' create temporary table on sql server
Using dbCmd As SqlCommand = New SqlCommand
dbCmd.Connection = dbConn
dbCmd.Transaction = dbTran
dbCmd.CommandType = CommandType.Text
dbCmd.CommandText = "create table #tempTable (your fields here)"
dbCmd.ExecuteNonQuery
End Using
' fill temp table
Using sbc As SqlBulkCopy = New SqlBulkCopy(dbConn, SqlBulkCopyOptions.Default, dbTran)
sbc.BatchSize = 1000
' no explicit mapping between source and destination fields
' because both tables have the very same field names
sbc.DestinationTableName = "#tempTable"
sbc.WriteToServer(sapCustomer)
End Using
' handle the steps needed to copy/move the data to the final destination
Using dbCmd As SqlCommand = New SqlCommand
dbCmd.Connection = dbConn
dbCmd.Transaction = dbTran
dbCmd.CommandType = CommandType.Text
dbCmd.CommandText = "insert into finaltable select field1, field2 from #tempTable"
dbCmd.ExecuteNonQuery
End Using
вышеприведенный код успешно обрабатывает xml-документы 50mb + с 50k-записями за 1 минуту.
тяжелая задача - копирование данных из xml в datatable: куча secs для загрузки, 40 секунд для xml -> datatable и 2 секунды для обработки базы данных.
если ваши данные находятся в более «дружественном к дате» формате, вы можете легко достичь лучших результатов.