为什么UNION运算符会导致OracleDataAdapter中的数据类型更改?

时间:2017-12-07 16:02:12

标签: c# sql oracle oracle10g dataadapter

我在过程P_GET_TABLE1中嵌入了以下查询:

SELECT 
  t1.field1 XXXX
FROM table1 t1

field1NUMBER(12)。该过程在使用OracleDataAdapter的.NET代码中完成,并填充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更改数据类型?
  • 我可以强制OracleDataAdapterXXXX解释为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 个答案:

答案 0 :(得分:2)

为此狩猎:

集合操作的文档(包括UNION)链接到更常规的文档部分,用于"隐式数据转换" - 我们可以在哪里阅读:

在操作数值时,Oracle通常会调整精度和比例以允许最大容量。在这种情况下,此类操作产生的数值数据类型可能与基础表中的数值数据类型不同。

在您的示例中,UNION的第二个分支生成值0,而不是显式转换为任何精度和比例。因此,默认情况下,该0被认为是NUMBER类型(具有精度38和未确定的比例)。当您使用UNION时,数据类型将是"最大容量",即NUMBER。

解决方案是在CAST中包裹0:cast(0 as number(12)) ....