CHAR(1) 字段中出现 ORA-12899 错误,但我只发送“C”

发布于 2024-08-31 05:03:57 字数 196 浏览 5 评论 0原文

我的 Oracle 数据库返回错误:

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

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

任何人都知道为什么会发生这种情况?

(我使用 C# 和 ODP.NET)

My Oracle database returns the error:

ORA-12899 - Value too large for column
TIT.ESTADO_CIVIL (actual: 2, maximum:
1)

But I'm very sure that the sended value is an unique char 'C'.

Anyone knows why this is happening?

(I'm using C# with ODP.NET)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我乃一代侩神 2024-09-07 05:03:57

“C# 字符有 16 位;谷歌搜索
告诉我 Oracle CHAR 类型是 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>

该文档有很多有关全球化和字符集的有用信息。您没有说明您正在使用哪个版本的数据库,因此这里有一个 有关长度语义的 9i 文档

"The C# char has 16 bits; googling
tells me that Oracle CHAR types are 8
bits."

There are a couple of ways of dealing with this. The best solution would be to fix the database so it uses character semantics.

alter system set nls_length_semantics = char
/ 

As this has major ramifications you need to be sure that it solves your problem. Modify your table to use character semantics and see whether it removes the ORA-12899 exceptions.

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>

The documentation has a lot of helpful information on globalization and character sets. You don't say which version of the database you're using, so here's a link to the 9i docs on Length Semantics.

〆一缕阳光ご 2024-09-07 05:03:57

根据已接受的答案,在数据库级别进行修复似乎是最好的主意 - 因为它可以避免任何令人惊讶的行为。

但是,如果您不想在数据库级别修复(或无法访问),有两种方法可以帮助我实现此目的。我不确定第二个,但想分享它,以防有人发现它有用/可以解释它。

我的问题

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

    IDbDataParameter parm = command.CreateParameter();
    parm.ParameterName = "我的名字";
    parm.ParameterValue = 'A'; // 一个 C#(16 位)字符
    

这会遇到原始发布者提到的值对于列来说太大错误。

解决方案 1

设置值后手动覆盖 OracleType

((OracleParameter)parm).OracleType = OracleType.Char;

解决方案 2

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

parm.ParameterValue = "A"; // "A" instead of 'A'

Fixing at the database level seems like the best idea, as per the accepted answer - as it avoids any surprising behaviour.

However, if you don't want to fix (or can't access) at the database level, two ways worked for me to get this working. I'm not sure about the second one, but wanted to share it in case someone found it useful / could explain it.

My issue

  • Oracle stored procedure takes input parameter of type char (1 byte), which is used to set the value of a char (1 byte) column
  • I'm using System.Data.OracleClient.OracleCommand

    IDbDataParameter parm = command.CreateParameter();
    parm.ParameterName = "myname";
    parm.ParameterValue = 'A'; // a C# (16 bit) char
    

This hits the value too large for column error that the original poster mentions.

Solution 1

Override the OracleType by hand after setting the value:

((OracleParameter)parm).OracleType = OracleType.Char;

Solution 2

Slightly more dodgy - just use a string (I don't understand why this works, so would be wary of relying on it):

parm.ParameterValue = "A"; // "A" instead of 'A'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文