Я написал небольшое консольное приложение, которое указывает на папку, содержащую файлы DBF / FoxPo.
Затем оно создает таблицу в SQL на основе каждой таблицы dbf, затем выполняет массовую копию для вставкиданные в SQL.По большей части это работает довольно хорошо, за исключением нескольких ошибок.
1) Некоторые из таблиц FoxPro содержат 5000000+ записей, и соединение завершается до завершения вставки.
Здесьмоя строка подключения:
<add name="SQL" connectionString="data source=source_source;persist security info=True;user id=DBFToSQL;password=DBFToSQL;Connection Timeout=20000;Max Pool Size=200" providerName="System.Data.SqlClient" />
Сообщение об ошибке: "Время ожидания истекло. Время ожидания истекло до завершения операции, или сервер не отвечает."
КОД:
using (SqlConnection SQLConn = new SqlConnection(SQLString))
using (OleDbConnection FPConn = new OleDbConnection(FoxString))
{
ServerConnection srvConn = new Microsoft.SqlServer.Management.Common.ServerConnection(SQLConn);
try
{
FPConn.Open();
string dataString = String.Format("Select * from {0}", tableName);
using (OleDbCommand Command = new OleDbCommand(dataString, FPConn))
using (OleDbDataReader Reader = Command.ExecuteReader(CommandBehavior.SequentialAccess))
{
tbl = new Table(database, tableName, "schema");
for (int i = 0; i < Reader.FieldCount; i++)
{
col = new Column(tbl, Reader.GetName(i), ConvertTypeToDataType(Reader.GetFieldType(i)));
col.Nullable = true;
tbl.Columns.Add(col);
}
tbl.Create();
BulkCopy(Reader, tableName);
}
}
catch (Exception ex)
{
// LogText(ex, @"C:\LoadTable_Errors.txt", tableName);
throw ex;
}
finally
{
SQLConn.Close();
srvConn.Disconnect();
}
}
private DataType ConvertTypeToDataType(Type type)
{
switch (type.ToString())
{
case "System.Decimal":
return DataType.Decimal(18, 38);
case "System.String":
return DataType.NVarCharMax;
case "System.Int32":
return DataType.Int;
case "System.DateTime":
return DataType.DateTime;
case "System.Boolean":
return DataType.Bit;
default:
throw new NotImplementedException("ConvertTypeToDataType Not implemented for type : " + type.ToString());
}
}
private void BulkCopy(OleDbDataReader reader, string tableName)
{
using (SqlConnection SQLConn = new SqlConnection(SQLString))
{
SQLConn.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(SQLConn);
bulkCopy.DestinationTableName = "schema." + tableName;
try
{
bulkCopy.WriteToServer(reader);
}
catch (Exception ex)
{
//LogText(ex, @"C:\BulkCopy_Errors.txt", tableName);
}
finally
{
SQLConn.Close();
reader.Close();
}
}
}
Мои 2-я и 3-я ошибки следующие:
Я понимаю, что такое проблемы, но как их исправитьих я не так уверен
2) "Поставщик не смог определить десятичное значение. Например, строка была только что создана, значение по умолчанию для столбца« Десятичное число »было недоступно, а потребительеще не установил новое десятичное значение. "
3) SqlDateTime переполнение.Должно быть между 01.01.1753 12:00:00 и 31.12.9999 23:59:59.
Я нашел результат в Google, который указал, в чем проблема: [A] ... и возможная работа вокруг [B] (но я бы хотел сохранить мои десятичные значения как десятичные, а даты как дату, как я буду делатьдальнейшие расчеты с данными)
Что я хочу сделать в качестве решения
1.) Либо увеличьте время соединения, (но я не думаю, что смогуувеличить его больше, чем у меня), или, в качестве альтернативы, возможно ли разделить результаты OleDbDataReader и сделать это при инкрементной массовой вставке?
2.) Я думал, возможно ли иметь массовую копию, чтобы игнорировать результаты с ошибкамиили у вас есть записи об ошибках, записываемые в CSV-файл или что-то в этом роде?