Подтвердить что ты не робот

"Указанный приведение недействительно" при заполнении 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, но не на С#?

4b9b3361

Ответ 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