C# 字符(1)字段中出现ORA-12899错误,但I';我只发送一个';C';

C# 字符(1)字段中出现ORA-12899错误,但I';我只发送一个';C';,c#,oracle,oracle10g,odp.net,ora-12899,C#,Oracle,Oracle10g,Odp.net,Ora 12899,我的Oracle数据库返回错误: ORA-12899-列的值太大 TIT.ESTADO_CIVIL(实际值:2,最大值: (一) 但我非常确定发送的值是唯一的字符'C' 有人知道为什么会这样吗 (我将C#与ODP.NET一起使用) “字符有16位;谷歌搜索 告诉我Oracle字符类型是8 位。” 有几种方法可以解决这个问题。最好的解决方案是修复数据库,使其使用字符语义 alter system set nls_length_semantics = char / 由于这会产生重大影响,您需要确

我的Oracle数据库返回错误:

ORA-12899-列的值太大 TIT.ESTADO_CIVIL(实际值:2,最大值: (一)

但我非常确定发送的值是唯一的字符'C'

有人知道为什么会这样吗

(我将C#与ODP.NET一起使用)

“字符有16位;谷歌搜索 告诉我Oracle字符类型是8 位。”

有几种方法可以解决这个问题。最好的解决方案是修复数据库,使其使用字符语义

alter system set nls_length_semantics = char
/ 
由于这会产生重大影响,您需要确保它能解决您的问题。修改表以使用字符语义,并查看它是否删除ORA-12899异常

SQL> create table t69 (col1 char(1 byte))
  2  /

Table created.

SQL> desc t69
 Name          Null?    Type
 ------------- -------- ----------------
 COL1                   CHAR(1)


SQL> alter table t69 modify col1 char(1 char)
  2  /

Table altered.

SQL> desc t69
 Name          Null?    Type
 ------------- -------- ----------------
 COL1                   CHAR(1 CHAR)

SQL>

文档中有很多关于全球化和字符集的有用信息。您没有说明使用的是哪个版本的数据库,所以这里有一个链接

根据公认的答案,在数据库级别进行修复似乎是最好的主意,因为它避免了任何令人惊讶的行为

但是,如果您不想在数据库级别修复(或无法访问),我有两种方法可以让它正常工作。我不确定第二个,但想分享一下,以防有人发现它有用/可以解释

我的问题

  • Oracle存储过程采用类型为
    char(1字节)
    的输入参数,用于设置
    char(1字节)
    列的值
  • 我正在使用
    System.Data.OracleClient.OracleCommand

    IDbDataParameter parm = command.CreateParameter();
    parm.ParameterName = "myname";
    parm.ParameterValue = 'A'; // a C# (16 bit) char
    
对于原始海报中提到的列错误,这会命中太大的

解决方案1

设置值后手动覆盖
OracleType

((OracleParameter)parm).OracleType = OracleType.Char;
解决方案2

稍微有点狡猾-只需使用字符串(我不明白为什么这样做有效,所以要小心依赖它):


您是否真的发送了一个多字节的Unicode字符?C#char有16位;Google告诉我Oracle的字符类型是8位的。
parm.ParameterValue = "A"; // "A" instead of 'A'