我们正在开发一个将数据存储在数据库中的独立应用程序。我们使用Dataset和TableAdapters与数据库进行通信。其中一个基本要求是能够使用SQL Server,Oracle和MySQL的应用程序。为此,我们在TA供应商中独立进行了查询。我们使用ODBC提供程序。
它适用于SQL Server和MySQL,但是使用Oracle我们遇到了问题。我们无法克服的一个问题是十进制到Int64的转换错误。
Oracle表使用NUMBER(38)表示系统ID(自动增量字段),因为它似乎映射到十进制。但是我们在DataSet / TA中使用Int64 / long,因为SQL Server和MySQL使用BIGINT。 (注意DataSEt TableAdapters从一开始就从SQL Server架构自动生成。)
我们从Oracle获取NUMBER值时会收到强制转换异常,因为它返回一个小数对象。
DbCommand getIDcmd = connection.CreateCommand();
getIDcmd.CommandText = "select LAST_ID from SEQUENCE_ID";
sequenceID = (Int64)getIDcmd.ExecuteScalar(); // we get a cast exception here returns decimal
请注意,我们已尝试降低Oracle中的精确度(例如NUMBER(10)),正如我们在其他论坛条目中看到的那样,但没有运气。
这是ODBC问题吗?如果我们转移到其他提供商将解决问题?
答案 0 :(得分:1)
如果sequence_id
是序列的名称,则查询在Oracle中看起来不正确。您可以使用以下查询查询最后给定的ID:
SELECT last_number FROM all_sequences WHERE sequence_owner=? AND sequence_name=?
演员阵容应该不是问题(如果在int64范围内)。
答案 1 :(得分:1)
你可以运行它来找出实际返回的类型,然后从那里开始:
System.Windows.Forms.MessageBox.Show(getIDcmd.ExecuteScalar().GetType().ToString());
答案 2 :(得分:1)
似乎此查询将始终返回“十进制”。你可以试试这个:
sequenceID = Convert.ToInt64(getIDcmd.ExecuteScalar());
我认为在您的情况下不会出现任何精度损失。
请注意,降低NUMBER的精确度总是一个好主意:Int64
映射到NUMBER(19)
。
这不会解决您手头的问题,但可能会在将来阻止更多问题。例如,如果您获得包含您的ID的IDataRecord
(使用Microsoft Oracle提供程序),则当您的列定义为NUMBER(38)
时,对GetInt64
的调用将失败,并且在定义为{时成功{1}}(即使值在正确的范围内)。