Почему оператор UNION вызывает изменение типа данных в OracleDataAdapter?

У меня есть следующий запрос, встроенный в процедуру P_GET_TABLE1:

SELECT 
  t1.field1 XXXX
FROM table1 t1

field1 является NUMBER(12), Процедура выполняется в коде.NET с использованием OracleDataAdapter и заполняет DataTable такой, что XXXX превращается в long,

У меня другая процедура P_GET_TABLE2:

SELECT 
  t1.field1 XXXX
FROM table1 t1
UNION
SELECT
  0 as XXXX
FROM table2

Однако объединение, похоже, вызывает изменение типа данных, так что XXXX не может быть преобразован в long, только decimal,

Мои вопросы:

  • Почему UNION Оператор вызывает OracleDataAdapter изменить тип данных?
  • Могу ли я заставить OracleDataAdapter интерпретировать XXXX как long

В частности, этот код используется для получения данных:

OracleDataAdapter da = new OracleDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.Fill(dt);
foreach(DataRow row in da.Rows)
{
    long value = (long)row["XXXX"]; // works when P_GET_TABLE1; exception when P_GET_TABLE2 is used; 
}

Исключение: 'Object of type 'System.Decimal' cannot be converted to type 'System.Int64'.'

1 ответ

Решение

Охота это для вас:

Документация по операциям над множествами (включая UNION) связана с более общим разделом документации по "неявному преобразованию данных", где мы можем прочитать:

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

В вашем примере вторая ветвь UNION создает значение 0, явно не приведенное к какой-либо точности и масштабу. Таким образом, по умолчанию этот 0 считается с типом NUMBER (который имеет точность 38 и неопределенный масштаб). Когда вы UNION, тип данных будет "максимальная емкость", которая является NUMBER.

Решение состоит в том, чтобы обернуть 0 в CAST: cast(0 as number(12)) ....

Другие вопросы по тегам