c# OracleParameter 抛出 ORA-06502

Posted

技术标签:

【中文标题】c# OracleParameter 抛出 ORA-06502【英文标题】:c# OracleParameter throws ORA-06502 【发布时间】:2020-07-09 09:27:55 【问题描述】:

我有具有以下功能的 Oracle 数据库

create or replace PACKAGE PCK_A IS

FUNCTION InsertPerson(
    pi_FirstName IN person.firstname%type,
    pi_LastName IN person.lastname%type,
    pi_CompanyName IN person.companyname%type,
    pi_Email IN person.emailaddress%type,
    pi_Phone IN phonenumbers.phoneno%type,
    pi_User IN user.name%type
) RETURN NUMBER;

表PERSON定义为

CREATE TABLE "person" ( 
  "ID" NUMBER(7,0) NOT NULL ENABLE,  
  "EMAILADDRESS" VARCHAR2(60 BYTE),
  "FIRSTNAME" VARCHAR2(50 BYTE) DEFAULT NULL, 
  "LASTNAME" VARCHAR2(50 BYTE) DEFAULT NULL, 
  "COMPANYNAME" VARCHAR2(100 BYTE) DEFAULT NULL, 
   CONSTRAINT "PK_PERSON" PRIMARY KEY ("ID"));

我需要在 C# 代码中调用这个函数,所以我创建了以下方法:

public long InsertPerson(OracleConnection connection, OracleTransaction transaction) 
  using (var cmd = connection.CreateCommand()) 
    cmd.Transaction = transaction;
    cmd.CommandText = @"begin 
                          :personId := PCK_A.InsertPerson('Name', 'Surname', 'Company', 'mail@company.com', '123456789', 'user'); 
                        end;";
    cmd.Parameters.Add("personId", OracleDbType.Decimal, ParameterDirection.ReturnValue).Size = 7;
    cmd.ExecuteNonQuery();

    return ((OracleDecimal) cmd.Parameters["contactPersonId"].Value).ToInt64();
   

此代码可以正常工作。但是当我使用 OracleParameter 作为函数参数 ExecuteNonQuery 抛出: Oracle.DataAccess.Client.OracleException: 'ORA-06502: PL/SQL: numeric or value error: 字符串缓冲区太小 ORA-06512: 在第 2 行'

这是导致问题的 C# 调整方法:

public long InsertPerson(OracleConnection connection, OracleTransaction transaction) 
   using (var cmd = connection.CreateCommand()) 
      cmd.Transaction = transaction;
      cmd.CommandText = @"begin 
                             :personId := PCK_A.InsertPerson(:pFirstName, 'Surname', 'Company', 'mail@company.com', '123456789', 'user'); 
                          end;";
      cmd.Parameters.Add("pFirstName", OracleDbType.Varchar2, 50, contact.FirstName, ParameterDirection.Input);
      cmd.Parameters.Add("personId", OracleDbType.Decimal, ParameterDirection.ReturnValue).Size = 7;
      cmd.ExecuteNonQuery();

      return ((OracleDecimal) cmd.Parameters["contactPersonId"].Value).ToInt64();
  

怎么了?

【问题讨论】:

【参考方案1】:

尝试删除此参数的.Size = 7; 部分。这是以字节为单位的大小,而 Oracle 的 NUMBER(7, 0) 不会减少数字的内存大小,而只会在逻辑上限制可能的值(即它控制值最多为 7 个 digits,而不是 7 个 字节)

【讨论】:

谢谢。我已经尝试过了,但它并没有解决问题。参数pFirstName 似乎有问题,因为没有它它可以工作,即使使用.Size = 7 您确定contact.FirstName 不超过50 个字节吗?因为如果您使用 Unicode 编码,那么 1 个字符不等于 1 个字节,因此即使 25 个字符也可能超出您的限制 contact.FirstName 的值是"M",所以它应该适合大小没有问题。

以上是关于c# OracleParameter 抛出 ORA-06502的主要内容,如果未能解决你的问题,请参考以下文章

ora-01036: 非法的变量名/编号

C# OracleParameter 执行增删改查 实例

无法将“System.String”类型的对象转换为 C# 中的“Oracle.DataAccess.Client.OracleParameter”类型

OracleParameter 对象已包含在集合中

C# ORA-06502 中的存储过程

OracleConnection.Open 抛出 ORA-12541 TNS no listener