简体   繁体   English

Oracle存储过程输出参数值

[英]Oracle Stored Procedure out parameter value

One of our clients inherited a fairly large PMS based on asp.net/oracle. 我们的一位客户继承了基于asp.net/oracle的相当大的PMS。 Unfortunately my knowledge of oracle is minimal and I'm having a few issues:- 不幸的是,我对oracle的了解很少,而且我遇到了一些问题:

Original system was based around Oracle 9 and is using the System.Data.OracleClient driver from MS. 原始系统基于Oracle 9,并使用MS的System.Data.OracleClient驱动程序。 The new client has opted for an Oracle 12c appliance box and the database was transferred successfully but some of the existing stored procedures are problematic - for instance 新客户端选择了Oracle 12c设备盒,并且数据库已成功传输,但是某些现有存储过程存在问题-例如

PROCEDURE IS_PROJECT_LEADER(A_PROJ_ID NUMBER, A_ACCOUNT_ID VARCHAR2, A_SUCCESS OUT VARCHAR2)
IS
    v_COUNT NUMBER;
BEGIN
    --Check if Project Leader, or in the Project Leader Group
    SELECT  COUNT(*)
    INTO    v_COUNT
    FROM    PROJ_ACCOUNT
    WHERE   PROJ_ID = A_PROJ_ID
    AND     ACCOUNT_ID = A_ACCOUNT_ID
    AND     (SYS_ROLE_ID = 3 OR IS_PL_GROUP = 'Y');

    IF v_COUNT > 0 THEN
        A_SUCCESS := 'Y';
    ELSE
        A_SUCCESS := 'N';
    END IF;
END;

The parameters are initialised using this code - not sure if this is correct or not in the oracle world? 使用此代码初始化参数-不确定在oracle世界中是否正确?

while (rdr.Read())
{
  prm = new OracleParameter();
  prm.ParameterName = rdr["ARGUMENT_NAME"].ToString();
  switch (rdr["DATA_TYPE"].ToString())
  {
    case "NUMBER":
      prm.OracleType = OracleType.Number;
      break;
    case "VARCHAR2":
      prm.OracleType = OracleType.VarChar;
      if (rdr["IN_OUT"].ToString() == "OUT"
        || rdr["IN_OUT"].ToString() == "IN/OUT")
      {
        prm.Size = 4000;
      }
      break;
    case "DATE":
      prm.OracleType = OracleType.DateTime;
      break;
    case "BLOB":
      prm.OracleType = OracleType.Blob;
      break;
      case "CLOB":
         prm.OracleType = OracleType.Clob;
         break;

        }
  switch (rdr["IN_OUT"].ToString())
  {
    case "IN":
      prm.Direction = ParameterDirection.Input;
      break;
    case "OUT":
      prm.Direction = ParameterDirection.Output;
      break;
    case "IN/OUT":
      prm.Direction = ParameterDirection.InputOutput;
      break;
  }
  prm.Value = System.DBNull.Value;
  cmd.Parameters.Add(prm);
}

The return value of A_SUCCESS in the current system is always an empty string. 当前系统中A_SUCCESS的返回值始终为空字符串。 If I remove the MS OracleClient and use the latest Oracle ODP.net drivers then the required string value is returned...or if I change the data type and return type of A_SUCCESS to CHAR then everything works. 如果删除MS OracleClient并使用最新的Oracle ODP.net驱动程序,则返回所需的字符串值...或者如果我将数据类型和A_SUCCESS的类型返回为CHAR,则一切正常。 There are plans to move to the ODP client as recommended by MS - however the system is fairly large and badly designed so won't be done for months. 按照MS的建议,有计划迁移到ODP客户端-但是该系统相当大且设计不当,因此几个月后将无法完成。

Am I right though in thinking this is a driver issue and not some esoteric Oracle functionality that I am unaware of? 我是否认为这是驱动程序问题,而不是我不知道的某些深奥的Oracle功能,对吗?

I currently work in Oracle 12c/c#.Net. 我目前在Oracle 12c / c#.Net中工作。 We do use Oracle's ODP driver which we've found to be more successful than Microsoft's driver. 我们确实使用了Oracle的ODP驱动程序,我们发现它比Microsoft的驱动程序更成功。

I'm changing the way I'm stating my answer because of the comment. 由于评论的原因,我正在改变说明答案的方式。 But I don't think I'm that far off. 但是我不认为我有那么远。 The accepted answer to the thread, Exception while executing stored procedure odp.net , given by MTO was to add the size or length of the varchar2 field to the parameter definition which is what I was trying to say. MTO给线程执行存储过程odp.net时Exception的可接受答案是将varchar2字段的大小或长度添加到参数定义中,这就是我要说的。 Even though A_SUCCESS isn't stored in the database, it requires storage to execute within the procedure. 即使A_SUCCESS没有存储在数据库中,它也需要存储才能在过程中执行。

Here's what we know: 这是我们所知道的:

  1. It worked when you changed the procedure datatype to CHAR. 当您将过程数据类型更改为CHAR时,它可以工作。
  2. You didn't change the parameter (prm) settings on the c# side which means the calling program used the same settings for VARCHAR2 as it did for CHAR. 您没有在c#端更改参数(prm)设置,这意味着调用程序对VARCHAR2使用的设置与对CHAR使用的设置相同。
  3. CHAR has a default length of 1. VARCHAR2's length has to be set. CHAR的默认长度为1。必须设置VARCHAR2的长度。
  4. It worked on 9i but not 12c. 它适用于9i,但不适用于12c。 The way VARCHAR2's are stored changed between 9i and 12c. VARCHAR2的存储方式在9i和12c之间改变。
  5. It works with ODP. 它与ODP一起使用。 This is strange if it's a length issue because ODP also needs the length of VARCHAR2 to be set. 如果是长度问题,这很奇怪,因为ODP还需要设置VARCHAR2的长度。

I'd try this: 我会尝试这样的:

  1. Print the contents of prm for each parameter to see what's actually being set. 打印每个参数的prm内容,以查看实际设置的内容。
  2. If A_SUCCESS isn't being set as VARCHAR2, make sure it is and that it has a length or size set. 如果未将A_SUCCESS设置为VARCHAR2,请确保已设置为VARCHAR2,并且已设置了长度或大小。
  3. I know it's a long shot but I'd try setting the length of A_SUCCESS in the procedure using a local variable. 我知道这是一个远景,但是我会尝试在过程中使用局部变量设置A_SUCCESS的长度。 I suggest it because changing the datatype to CHAR worked. 我建议这样做是因为将数据类型更改为CHAR是可行的。

Thanks for the help. 谢谢您的帮助。 Client decided to jumpstart the conversion to ODP as it seemed the most logical solution. 客户决定启动向ODP的转换,因为这似乎是最合乎逻辑的解决方案。 Working as expected. 工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Dapper.NET 从存储过程调用中获取 Oracle OUT 参数的值 - Get value of Oracle OUT parameter from a stored procedure call using Dapper.NET 如何使用 dapper 从 oracle 存储过程中获取参数 - How to get out parameter from oracle stored procedure using dapper 如何使ODP.NET从Oracle存储过程中的out参数返回用户定义类型的空值? - How to get ODP.NET to return null value for User Defined Type from out parameter in Oracle stored procedure? 使用out参数调用存储过程 - Calling a stored procedure with an out parameter 从存储过程,返回OUT参数和OUT游标和解析结果(Oracle) - From Stored Procedure, return OUT parameter & OUT cursor & parse result (Oracle) 修改存储过程参数值 - Modify Stored procedure parameter value Oracle存储过程抛出参数不匹配错误 - Oracle stored procedure throwing parameter mismatch error C#Oracle存储过程参数顺序 - C# Oracle Stored Procedure Parameter Order 如何使用实体框架调用接受 RefCursor 作为输出参数的 Oracle 存储过程 - How to call Oracle stored procedure which accepts RefCursor as out parameter using Entity Framework 使用PLS-00306调用带有Char Out参数错误的Oracle存储过程:调用中的参数数目或类型错误 - Call Oracle Stored Procedure with Char Out Parameter errors with PLS-00306: wrong number or types of arguments in call
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM