使用12c客户端截断的存储过程OUTPUT VARCHAR2值

时间:2017-03-17 11:54:04

标签: c# sql asp.net oracle11g ado.net

我正在使用 oracle 11g 。我的存储过程正在返回varchar2,但其值被oracle client截断。 以下是我的代码:

            if ((ds != null) && (ds.Tables.Count > 0))
                {

                    foreach (DataRow rw in ds.Tables[0].Rows)
                    {

                        OracleParameter param = new OracleParameter((rw["argument_name"]).ToString(), GetOracleType(rw["data_type"].ToString().ToUpper()));
                        param.Direction = GetParameterDirection((rw["in_out"]).ToString().ToUpper());
                        discoveryCommand.Parameters.Add(param);
                        if (param.Direction == ParameterDirection.Output && param.OracleType == OracleType.VarChar)
                        {
                            param.Size = 4000;
                        }
                    }
                }

我将param.size增加到4000,但仍然会截断值。 对此有什么解决方案吗?在服务器上我有 Oracle 12c 。我需要在我的项目中不更新oracle客户端版本的情况下获得解决方案,因为某些原因不允许这样做。

以下是SP。我修改它以返回硬编码值。还是一样的问题。

PROCEDURE access_level (
          p_emp_id IN  employees.emp_id%TYPE,
        p_id IN  NUMBER,
        p_type VARCHAR2,
          p_access_level OUT VARCHAR2
 ) IS
  BEGIN


 p_access_level := 'X' || 'RO' || 'RW';






 END IF;

3 个答案:

答案 0 :(得分:5)

对于连接到服务器12.1.0.1.0的客户端版本11.2.0.1.0,我无法重现您的问题。当Oracle 12c客户端截断输出变量时,它是known case,但是如果您使用的是11g版本的客户端,则不应该是您的情况。

我使用了以下测试表和存储过程:

CREATE TABLE TEST_TABLE
(
    ID NUMBER(11) NOT NULL,
    NAME VARCHAR2(256),
    CONSTRAINT TEST_TABLE_PK PRIMARY KEY (ID)
)
/

INSERT INTO TEST_TABLE(ID, NAME) VALUES(1, 'Some test data')
/

CREATE PROCEDURE TEST_PROCEDURE
(
   P_ID OUT NUMBER,
   P_NAME OUT VARCHAR2
)
AS
BEGIN
   SELECT ID, NAME INTO P_ID, P_NAME FROM TEST_TABLE;
END;

以下是正确提取数据的客户端代码:

using (OracleConnection connection = new OracleConnection())
{
    connection.ConnectionString = ConfigurationManager.ConnectionStrings["TestDatabase"].ConnectionString;
    connection.Open();

    using (OracleCommand command = connection.CreateCommand())
    {
        command.CommandText = "TEST_PROCEDURE";
        command.CommandType = CommandType.StoredProcedure;

        OracleParameter param1 = new OracleParameter("P_ID", OracleType.Number);
        param1.Direction = ParameterDirection.Output;
        command.Parameters.Add(param1);

        OracleParameter param2 = new OracleParameter("P_NAME", OracleType.VarChar);
        param2.Size = 4000;
        param2.Direction = ParameterDirection.Output;
        command.Parameters.Add(param2);

        using (command.ExecuteReader())
        {
            Console.WriteLine($"Output: [{param2.Value}]");
        }
    }
}

要继续提出您的问题,请执行以下操作:

  1. 如果可以创建上面的测试表和存储过程,并检查如何使用上面的代码获取字符串数据。
  2. 如果由于某种原因无法实现,请提供以下信息:

    • 调用存储过程的完整代码
    • 从事存储过程的所有表的DDL
    • 获取数据的完整客户端代码
  3. 魔鬼永远在细节中。我们应该理解你的情况与上面的工作示例代码有什么不同。

答案 1 :(得分:2)

我试图通过迁移到ODP.NET来解决问题,因为System.Data.OracleClient已被Microsoft弃用here ,但问题没有解决。以下是问题的解决方法:

  1. 计算机12.1.0.2.2
  2. 上安装的Oracle客户端版本 {li> Output parameter truncation错误在Oracle文档中被提及为Bug21616079
  3. Oracle已根据12.2.0.1.0文档here中提及的版本Oracle进行了修复。
  4. 因此,12.2.0.1.012.1.0.2.2升级到版本Oracle已修复了此问题,因为Oracle已在此版本中修复了此问题,我在官方- (void)postNotificationName:(NSNotificationName)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo; 文档中提及了在第3点提供了上面的链接。

答案 2 :(得分:0)

我在64位Windows OS上都遇到了与客户端10g和服务器11g相同的问题,我通过将.net应用程序托管在IIS上并将app_pool的高级设置“启用32位应用程序”更改为False来解决了这个问题。