Почему оператор 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)) ....