C#:Oracle 数据类型与 OracleDbType 等价
Posted
技术标签:
【中文标题】C#:Oracle 数据类型与 OracleDbType 等价【英文标题】:C#: Oracle Data Type Equivalence with OracleDbType 【发布时间】:2010-12-07 16:14:33 【问题描述】:情况:
我正在 C# 中创建一个应用程序,该应用程序使用 Oracle.DataAccess.Client (11g) 对带有存储过程的 Oracle 数据库执行某些操作。我知道有一个包含 Oracle 数据类型的特定枚举 (OracleDbType),但我不确定将哪个枚举用于某些类型。
问题:
什么是等效的Oracle PL/SQL 数据 type 中的每个枚举类型 OracleDbType 枚举?
整数分为三种类型 (Int16, Int32, Int64) 在OracleDbType...怎么知道 使用哪一个或者它们都是 想工作吗?
【问题讨论】:
如果出现错误,请检查您是否以正确的顺序添加 OracleParameters。这是必需的,即使这些是命名参数。将每个 OracleParameter 的 .Direction 显式设置为 Input、Output 或 InputOutput 也是一个不错的主意。 【参考方案1】:这是一种将 C# 类型转换为最常见的 OracleDbTypes 的方法
private static OracleDbType GetOracleDbType(object o)
if (o is string) return OracleDbType.Varchar2;
if (o is DateTime) return OracleDbType.Date;
if (o is Int64) return OracleDbType.Int64;
if (o is Int32) return OracleDbType.Int32;
if (o is Int16) return OracleDbType.Int16;
if (o is sbyte) return OracleDbType.Byte;
if (o is byte) return OracleDbType.Int16; -- <== unverified
if (o is decimal) return OracleDbType.Decimal;
if (o is float) return OracleDbType.Single;
if (o is double) return OracleDbType.Double;
if (o is byte[]) return OracleDbType.Blob;
return OracleDbType.Varchar2;
另外,对于非常大的字符数据值,您可能需要使用OracleDbType.Clob
。
【讨论】:
顺便说一下Oracle PL/SQL数据类型。 那里有两个“if(o is byte)” :)byte -> OracleDbType.Byte
是错误的。当您使用此cmd.Parameters.Add("p1", OracleDbType.Byte, ParameterDirection.Input).Value = 129
时,Oracle DB 会收到 -127。我偶然发现了这一点。因此OracleDbType.Byte
匹配sbyte
。对于 bytes
值,您必须使用 OracleDbType.Int16
才能覆盖 0..255【参考方案2】:
OracleDbType 枚举的值在文档中定义。阅读the ODP for .NET Developer's Guide。
关于在 Int16、Int32 和 Int64 之间进行选择,它们都应该可以工作。选择与您的 .Net 变量的预期大小匹配的一个:Int16 用于 -32768 和 32767 之间的值,Int32 用于 -2147483648 和 2147483647 之间的值,Int64 用于更大的值。转换 Ints 和 PL/SQL 数据类型似乎有些有趣。检查this blog post by Mark Williams。
尾声
来自 2021 年的问候。这篇文章刚刚获得了投票,所以大概搜索者仍在寻找它并发现它很有用。但请注意,已经有十多年的历史了。因此,它提供的建议可能与最新版本的 ODP 无关,尤其是关于异常行为。请不要在没有亲自验证的情况下遵循建议。 (这是适用于您在 Internet 上阅读的任何内容的一般建议,而不仅仅是关于软件开发!)
Here is the pertinent link for Oracle 21c ODP documentation.
【讨论】:
即使在 2021 年,这篇文章仍然有用。我想知道 Oracle 类型NUMBER
应该绑定到 OracleDbType
的什么值,感谢您的链接,我找到了答案。【参考方案3】:
检查APC's links,它们就是您要查找的内容:根据枚举的名称,映射非常简单。
但正如您开始注意到的那样,整数有些棘手。这是我的地图:
Int16
: NUMBER(5)
.
Int32
: NUMBER(10)
.
Int64
: NUMBER(19)
.
问题是,如果您在 NUMBER(38)
列上调用 GetInt64
,即使值在正确的范围内,您也会收到异常...
【讨论】:
【参考方案4】:NUMBER(1,0) => 布尔值
NUMBER(5,0) => Int16.MaxValue == 32767
NUMBER(10,0) => Int32.MaxValue == 2,147,483,647
NUMBER(19,0) => Int64.MaxValue == 9,223,372,036,854,775,807
NUMBER(19,0) => long.MaxValue == 9,223,372,036,854,775,807
【讨论】:
【参考方案5】:对于那些想知道de浮点等价物的人:
Decimal Oracle NUMBER type
Double 8-byte FLOAT type
如果你在 oracle 中使用数字,十进制是要走的路。
正如 APC 指出的那样: https://docs.oracle.com/cd/B19306_01/win.102/b14307/OracleDbTypeEnumerationType.htm
【讨论】:
以上是关于C#:Oracle 数据类型与 OracleDbType 等价的主要内容,如果未能解决你的问题,请参考以下文章
c# OracleDataAdapter.Fill 遇到不支持的 Oracle 数据类型