DataReader возвращает неверный тип данных .net для плавающего столбца таблицы базы данных. - PullRequest
5 голосов
/ 24 апреля 2019

У меня есть 1 таблица в Oracle SQL Developer, которая содержит 1 column as Float. Data reader должна вернуть Decimal for oracle float datatype согласно таблице, приведенной здесь: https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/oracle-data-type-mappings

Но проблема в том, что datareader возвращает double as datatype для Float Column, как показано ниже: enter image description here

Но проблема в том, что datareader возвращает double в качестве типа данных для NREAL as Float и NFLOAT1 as float, что удивительно DataReader возвращает Decimal for both the column, как показано ниже:

enter image description here

код:

static void Test()
        {
            using (OracleConnection connection = new OracleConnection("connection string")
            {
                connection.Open();
                using (OracleCommand command = connection.CreateCommand())
                {
                    command.CommandText = "select id , NFLOAT from Numeric_Table";
                    using (OracleDataReader reader = command.ExecuteReader())
                    {
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            var columnName = reader.GetName(i);
                            var dotNetType = reader.GetFieldType(i);
                            var sqlType = reader.GetDataTypeName(i);
                        }
                    }
                }
            }
        }

Я использую: Oracle.ManagedDataAccess.Client

Это ошибка внутри Oracle.ManagedDataAccess.Client library или я что-то не так делаю?

Обновление: На основании комментариев хочу кое-что упомянуть:

Хотя у меня может быть ссылка на другую исходную документацию, не применимую к используемой мной библиотеке оракула, но, тем не менее, я получаю десятичный тип данных для двух других моих столбцов, то есть NREAL и NFLOAT1, так почему это поведение не согласовано?

1 Ответ

1 голос
/ 25 апреля 2019

Тип данных FLOAT не является полной картиной. Разработчик SQL не показывает, что NFLOAT имеет точность менее 50, в то время как NREAL и NFLOAT1 имеют точность 50 или выше. При создании не указывается точность по умолчанию 126, что составляет максимально возможная точность для типа данных FLOAT .

Простой тестовый запрос продемонстрирует разницу:

SELECT CAST(0 AS FLOAT(49)), CAST(0 AS FLOAT(50)) FROM DUAL

Первый столбец будет возвращен как System.Double. Второй будет возвращен как System.Decimal.

В SQL Developer щелкните правой кнопкой мыши таблицу и выберите «Редактировать ...». В этом диалоговом окне показывает заданную точность для столбца.

Если вы хотите, чтобы NFLOAT было возвращено как System.Decimal, увеличьте точность как минимум до 50.


В последнее время я прочесываю документацию и запускаю собственные тесты. Это любимый проект, и я не пользуюсь Oracle регулярно, поэтому было много проб и ошибок. Функция DUMP очень помогла определить, правильно ли указан тип данных в выражении, прежде чем посмотреть, что с ним делает ODP .NET.

В качестве другого примера того, как ODP .NET возвращает разные типы данных в зависимости от точности, рассмотрим NUMBER(p,0).

Type     Min p    Max p
---------------------------
Int16    1        4
Int32    5        9
Int64    10       18
Decimal  19       38

Я надеялся, что Byte или SByte будут возвращены, когда p равно 1 или 2, но это не сработало.

...