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 -&gt; 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#读取oracle数据库中的long类型字段

c# OracleDataAdapter.Fill 遇到不支持的 Oracle 数据类型

Oracle的Number对应C#数据类型

创建调用 ORACLE 数据库以获取指定类型对象的 DDL 的 C# 例程

关于Oracle Spatial的数据格式 C#

C# 数据库访问:DBNull 与 null