#c# #oracle #copy #odp.net #bulk
#c# #Oracle #Копировать #odp.net #массовый
Вопрос:
Я использую ODP.NET и Oracle 10g для передачи данных из datatable в таблицу db. Проблема, с которой я сталкиваюсь, заключается в попытке вставить значение в столбец NUMBER (12,3). Значение равно 100100100,55 — я получаю сообщение об ошибке: Ошибка в строке ‘1’, столбце ‘6’ ORA-26093: размер столбца входных данных (24) превышает максимальный размер входных данных (22)
Но если я попробую 100100100,5, все будет работать нормально
Это сообщение об ошибке не имеет для меня никакого значения.
Кто-нибудь может объяснить мне, почему? Спасибо!
Также вот фрагмент, который выдает эту ошибку :
OracleBulkCopy bc = new OracleBulkCopy(DBFacade.DbConnection);
DataTable dt = new DataTable();
dt.Columns.Add();
dt.Rows.Add(100100100.11);
bc.DestinationTableName = "tmp_import_bom";
bc.ColumnMappings.Add(0, "QTY");
bc.WriteToServer(dt);
Комментарии:
1. Думая об этом, я думаю, что мой ответ бесполезен, поэтому я удалил его, я думаю, что в этой ошибке есть что-то специфичное для Oracle, поскольку, похоже, говорится, что ваш номер, состоящий всего из 12 цифр, имеет размер 24 и не может поместиться в размер 22. Я бы предложил отредактировать этот вопрос, особенно заголовок, чтобы сделать его общим вопросом Oracle, и вы могли бы привлечь к нему гораздо больше людей и, надеюсь, получить лучший ответ.
2. Ваш столбец равен 12,3, так почему же вы получаете данные, превышающие максимальный ввод 22?
3. какая версия ODP.net
4. это версия 11.1.0. Я также отредактировал вопрос и добавил пример кода c #, который выдает это исключение
5. Интересно,
100100100.11
хранится ли это внутри как число с плавающей запятой, которое, возможно, невозможно сохранить ровно через 2 места после десятичной запятой. Однако обычно я ожидаю, что при отправке в Oracle он автоматически усечет любое число с плавающей запятой до требуемой точности. Интересный вопрос.
Ответ №1:
Когда вы создаете подобный столбец DataTable в вашем примере кода, dt.Columns.Add()
он по умолчанию имеет тип string.
У меня была похожая проблема, и я обнаружил, что проблема заключается в том, что oracle bulk copy не может обрабатывать преобразование строк в десятичные или длинные, когда длина строки превышает 11.
Чтобы обойти проблему, вам нужно убедиться, что тип исходных данных является десятичным или длинным, а не строковым. В вашем примере кода вы могли бы сделать это с помощью dt.Columns.Add("QTY", typeof(decimal))
;
Подробные сведения:
Насколько я понимаю, сообщение об ошибке на самом деле сообщает нам, что максимальная длина строки для такого преобразования равна 11. Эти ссылки (24) и (22) в сообщении представляют собой длину строки входных данных и максимально допустимое значение x 2. Моя введенная строка была 26641778.595, что равно длине 12, включая десятичную точку. Если я добавлял цифру, сообщение менялось на (26) и т.д. Опять же, у меня также была такая же проблема с простым старым номером, например 123456789012, длина которого равна 12.
Ответ №2:
A NUMBER(12,3)
должен без проблем содержать значения, которые вы пытаетесь использовать. И если бы вы превышали точность числового столбца, более вероятно, что ошибка, которую вы получаете, была бы ORA-01438: value larger than specified precision allowed for this column
.
Похоже, ошибка может быть связана с другим столбцом в таблице. Похоже, что вы указываете только один столбец в своей вставке, но ошибка ссылается column '6'
. Каковы другие столбцы в таблице?
Ответ №3:
Ответ на этот вопрос содержится в Oracle doument «OracleBulkCopy выдает ORA-26093 при точной вставке в столбец NUMBER (идентификатор документа 1382276.1)».
Короче говоря:
ПРИЧИНА: Это предусмотрено проектом и ожидаемым поведением. Тип по умолчанию — системный.Строка.
РЕШЕНИЕ: укажите тип данных столбца
Поэтому вместо:
dt.Columns.Add();
следует написать:
DataColumn dc = new DataColumn();
dc.DataType = Type.GetType("System.Double");
dc.ColumnName = "QTY";
dt.Columns.Add(dc);
Ответ №4:
Обычно эта ошибка возникает из-за несоответствия метаданных, а не из-за ошибки значения. Подтвердите, что тип данных, который вы используете на .Сетевая сторона соответствует спецификации столбца number (12,3) на стороне ORacle. Попробуйте передать его как ‘double’ (преобразуя в double в приложении) и посмотрите, решит ли это проблему.