У меня есть код:
using (OracleCommand command = new OracleCommand(query, connection))
{
using (OracleDataReader reader = command.ExecuteReader())
{
using (var parser = new ChoParquetWriter(parquetSourcePath)
.Configure(c => c.RowGroupSize = 1000)
.NotifyAfter(1000)
.OnRowsWritten((o, e) => Console.WriteLine($"Rows: {e.RowsWritten} <--- {DateTime.Now}"))
.Setup(s => s.BeforeRecordFieldWrite += (o, e) =>
{
if (e.Source == DBNull.Value)
e.Source = null;
}))
{
if (reader.HasRows)
{
parser.Write(reader);
}
}
}
}
Запрос простой:
string query = $"SELECT x.*, x.ROWID FROM {owner}.{tableName} x";
В query
я запрашиваю строки из таблицы базы данных Oracle, где один столбец имеет тип TIMESTAMP. Я вижу, что парсер записывает первые 2000 строк без исключения. Но после начала записи еще одного пакета выдается исключение:
System.ArgumentOutOfRangeException: параметры Year, Month и Day описывают непредставимое значение DateTime. в Oracle.ManagedDataAccess.Types.DateTimeConv.ToDateTime(Byte[] byteRep, логическое значение isNotTimeStampTZ, смещение Int32, длина Int32) в Oracle.ManagedDataAccess.Client.OracleDataReader.GetDateTime(Int32 i) в Oracle.ManagedDataAccess.Client.OracleDataReader.GetValue(Int32 i) в ChoETL.ChoParquetWriter`1.Write(IDataReader dr)
Исключение выбрасывается в строке:
parser.Write(reader);
Я попыталась исправить это внутри .Setup
.Setup(s => s.BeforeRecordFieldWrite += (o, e) =>
{
if (e.Source == DBNull.Value)
e.Source = null;
else if (e.Source is DateTime dt)
{
if (dt < DateTime.MinValue || dt > DateTime.MaxValue)
e.Source = null; // or set to a default value
}
}))
или
.Setup(s => s.BeforeRecordFieldWrite += (o, e) =>
{
if (e.Source == DBNull.Value)
e.Source = null;
else if (e.Source is string str && DateTime.TryParse(str, out DateTime dt))
{
if (dt < DateTime.MinValue || dt > DateTime.MaxValue)
e.Source = null; // or set to a default value
else
e.Source = dt;
}
})
Но это не помогает.
Можете ли вы помочь мне с этим? Я подозреваю, что проблема связана с какой-то неудачной датой (например, 30 февраля), но как предотвратить выдачу исключения?
Есть ли исправление без изменения значения query
?
Да, это был бы разумный ход. К сожалению, у меня недостаточно прав для UPDATE или чего-либо другого, кроме SELECT. Я не могу контролировать данные внутри базы данных. Вот почему я делаю обходной путь. Обычно я бы исправил данные, но в данном случае я не могу.
Я изменил свой query
и добавил TO_CHAR для проблемных столбцов.
TO_CHAR(BIRTHDATE, 'YYYY-MM-DD HH24:MI:SS') AS BIRTHDATE
Теперь весь код работает.
Я не слишком хорошо знаком с БД Oracle. Но я бы проверил вашу базу данных на предмет поврежденного значения и исправил его. Обычно вы используете набор текста, чтобы избежать возникающих у вас проблем. Если (по какой-либо причине) ваши данные повреждены, исправьте их и не пытайтесь решить эту проблему.