"Указанный приведение недействительно" при заполнении DataTable из OracleDataAdapter.Fill()
Я не могу найти этот вопрос нигде в Google (или StackOverflow), который меня действительно удивил, поэтому я помещаю его сюда, чтобы помочь другим в той же ситуации.
У меня есть SQL-запрос, который отлично работает на Oracle Sql Developer, но когда я запускаю его через C#
с помощью adapter.Fill(table)
для получения результатов, я получаю ошибки Specified cast is not valid
(System.InvalidCastException
).
Вот вырезанная версия кода С#:
var resultsTable = new DataTable();
using (var adapter = new OracleDataAdapter(cmd))
{
var rows = adapter.Fill(resultsTable); // exception thrown here, but sql runs fine on Sql Dev
return resultsTable;
}
И вот упрощенная версия SQL:
SELECT acct_no, market_value/mv_total
FROM myTable
WHERE NVL(market_value, 0) != 0
AND NVL(mv_total, 0) != 0
Если я удаляю предложение о разделении, это не ошибка, поэтому он определен для этого. Тем не менее, как market_value, так и mv_total
имеют тип Number (19,4), и я вижу, что адаптер Oracle ожидает десятичную величину, так что кастинг происходит? Почему это работает на SqlDev, но не на С#?
Ответы
Ответ 1
Отвечая на мой собственный вопрос:
Таким образом, кажется, что тип номера Oracle может содержать гораздо больше десятичных знаков, чем десятичный тип С#, и если Oracle пытается вернуть больше, чем может удерживать С#, он выдает InvalidCastException.
Решение
В вашем sql округлите любые результаты, которые могут иметь слишком много десятичных знаков для чего-то разумного. Поэтому я сделал это:
SELECT acct_no, ROUND(market_value/mv_total, 8) -- rounding this division solves the problem
FROM myTable
WHERE NVL(market_value, 0) != 0
AND NVL(mv_total, 0) != 0
И это сработало.
Отказ: Несовместимость между типом номера Oracle и десятичным числом С#. Ограничьте десятичные места Oracle, чтобы избежать недопустимых исключений литых.
Надеюсь, это поможет кому-то еще!
Ответ 2
Я знаю, что эта тема действительно старая. Однако у меня была аналогичная проблема.
Лучшее решение, которое я должен использовать Oracle TO_BINARY_DOUBLE для столбца Oracle Decimal