Oracle ManagedDataAccess不从存储过程参数检索字符串

时间:2015-04-06 22:32:17

标签: c# oracle enterprise-library odp.net

对不起,如果我的英语不如我希望的那样好:D。 我使用VS2013并通过Nuget Package下载了ODP.NET。 我在Oracle数据库中调用sp中的方法。我已经能够建立连接,但是当我试图从输出参数中获取字符串值时,这个值为空。 int值检索ok但不检索字符串。 我用相同的值ej调用此方法。 employeeNumber = 431206,companyNumber = 0

这是我的网络配置文件connstring

<connectionStrings>
<add name="OracleMOC"
     connectionString="Data Source=(DESCRIPTION =(ADDRESS_LIST = (ADDRESS = (COMMUNITY = uri.world) (PROTOCOL = TCP) (Host = 14.85.65.12) (Port = 1521)))(CONNECT_DATA =(SID = SIOX)));User Id=***;Password=****;"
     providerName="Oracle.ManagedDataAccess.Client" />

我的代码

 public Employee GetEmployeeByNumber(string employeeNumber, int companyNumber)
    {
        Employee employee = new Employee();
            OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleMOC"].ToString());
            con.Open();
            OracleCommand cmd = con.CreateCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "SPR.GetEmployeeDetail";
            cmd.Parameters.Add("I_FEC_APROY", OracleDbType.Date, DateTime.Now, ParameterDirection.Input);
            cmd.Parameters.Add("I_FICHA", OracleDbType.Int32, Convert.ToInt32(employeeNumber.Trim()), ParameterDirection.Input);
            cmd.Parameters.Add("I_EMPCLAVE", OracleDbType.Int32, companyNumber, ParameterDirection.Input);
            cmd.Parameters.Add("O_RC", OracleDbType.Varchar2, 50000, ParameterDirection.InputOutput);
            cmd.Parameters.Add("O_PLAZA", OracleDbType.Varchar2, ParameterDirection.Output);
            cmd.Parameters.Add("O_NIVEL", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_NIVEL_P", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_CENTRO", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_DEPTO", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_DDEPTO", OracleDbType.Varchar2, 50000, ParameterDirection.InputOutput);
            cmd.Parameters.Add("O_AEMP", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_DEMP", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_FEC_RPROY", OracleDbType.Varchar2, 50000, ParameterDirection.InputOutput);
            cmd.Parameters.Add("O_VALIDO", OracleDbType.Varchar2, ParameterDirection.Output);
            cmd.Parameters.Add("O_FICHA", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_NOMBRE", OracleDbType.Varchar2, ParameterDirection.Output);
            cmd.Parameters.Add("O_APPAT", OracleDbType.Varchar2, ParameterDirection.Output);
            cmd.Parameters.Add("O_APMAT", OracleDbType.Varchar2, ParameterDirection.Output);
            cmd.Parameters.Add("O_ORGANISMO", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_NUMFAM", OracleDbType.Int32, ParameterDirection.Output);
            cmd.Parameters.Add("O_DESC_ORG", OracleDbType.Varchar2, ParameterDirection.Output);
            cmd.ExecuteNonQuery();

            employee.EmployeeNumber = employeeNumber;
            employee.CompanyNumber = companyNumber;
            employee.Regime = cmd.Parameters["O_RC"].Value.ToString();
            employee.Plaza = cmd.Parameters["O_PLAZA"].Value.ToString();
            employee.Level = cmd.Parameters["O_NIVEL"].Value.ToString();
            employee.Level_P = cmd.Parameters["O_NIVEL_P"].Value.ToString();
            employee.CenterNumber = cmd.Parameters["O_CENTRO"].Value.ToString() == "null" ? 0 : Convert.ToInt32(cmd.Parameters["O_CENTRO"].Value.ToString());
            employee.DepartmentNumber = cmd.Parameters["O_DEPTO"].Value.ToString() == "null" ? 0 : Convert.ToInt32(cmd.Parameters["O_DEPTO"].Value.ToString());
            employee.DepartmentDescription = cmd.Parameters["O_DDEPTO"].Value.ToString();
            employee.EmployeeYear = cmd.Parameters["O_AEMP"].Value.ToString() == "null" ? 0 : Convert.ToInt32(cmd.Parameters["O_AEMP"].Value.ToString());
            employee.EmployeeDay = cmd.Parameters["O_DEMP"].Value.ToString() == "null" ? 0 : Convert.ToInt32(cmd.Parameters["O_DEMP"].Value.ToString());
            employee.FirstName = cmd.Parameters["O_NOMBRE"].Value.ToString();
            employee.LastName = cmd.Parameters["O_APPAT"].Value.ToString();
            employee.LastName2 = cmd.Parameters["O_APMAT"].Value.ToString();

            employee.Organism = cmd.Parameters["O_ORGANISMO"].Value.ToString();

            if (cmd.Parameters["O_VALIDO"].Value.ToString() == "null")
                employee.IsValid = false;
            else
            {
                if (cmd.Parameters["O_VALIDO"].Value.ToString() == "true")
                {
                    employee.IsValid = false;
                }
                else
                {
                    employee.IsValid = true;
                }
            }

            employee.DateFinish = cmd.Parameters["O_FEC_RPROY"].Value.ToString();
            employee.OrganismDescription = cmd.Parameters["O_DESC_ORG"].Value.ToString();
            con.Close();

        return employee;

    }

我测试了相同的sp但使用同一个提供商的Enterprise Library。

public Employee GetEmployeeByNumber(string employeeNumber, int companyNumber)
    {            
        Employee employee = null;
        try
        {
            if (!String.IsNullOrEmpty(employeeNumber))
            {                    
                EmployeeDataSet ds = new EmployeeDataSet();
                DatabaseProviderFactory dbProviderFactory = new DatabaseProviderFactory();
                Database db = dbProviderFactory.Create("OracleMOC");

                DbCommand cmd = db.GetStoredProcCommand("SPR.GetEmployeeDetail");
                db.AddInParameter(cmd, "I_FEC_APROY", DbType.DateTime, DateTime.Now);
                db.AddInParameter(cmd, "I_FICHA", DbType.Int32, Convert.ToInt32(employeeNumber.Trim()));
                db.AddInParameter(cmd, "I_EMPCLAVE", DbType.Int32, companyNumber);
                db.AddOutParameter(cmd, "O_RC", DbType.String, 200);
                db.AddOutParameter(cmd, "O_PLAZA", DbType.String, 200);
                db.AddOutParameter(cmd, "O_NIVEL", DbType.Int32, 100);
                db.AddOutParameter(cmd, "O_NIVEL_P", DbType.Int32, 100);
                db.AddOutParameter(cmd, "O_CENTRO", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_DEPTO", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_DDEPTO", DbType.String, 200);
                db.AddOutParameter(cmd, "O_AEMP", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_DEMP", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_FEC_RPROY", DbType.DateTime, 200);
                db.AddOutParameter(cmd, "O_VALIDO", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_FICHA", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_NOMBRE", DbType.String, 200);
                db.AddOutParameter(cmd, "O_APPAT", DbType.String, 200);
                db.AddOutParameter(cmd, "O_APMAT", DbType.String, 200);
                db.AddOutParameter(cmd, "O_ORGANISMO", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_NUMFAM", DbType.Int32, 200);
                db.AddOutParameter(cmd, "O_DESC_ORG", DbType.String, 200);

                db.ExecuteNonQuery(cmd);

                if (String.IsNullOrEmpty(db.GetParameterValue(cmd, "O_NOMBRE").ToString()) && String.IsNullOrEmpty(db.GetParameterValue(cmd, "O_APPAT").ToString()))
                {
                    return employee;
                }
                else
                {
                    employee = new Employee();
                }
                employee.EmployeeNumber = employeeNumber;
                employee.CompanyNumber = companyNumber;
                employee.Plaza = db.GetParameterValue(cmd, "O_PLAZA").ToString();
                employee.Level = db.GetParameterValue(cmd, "O_NIVEL").ToString();
                employee.Level_P = db.GetParameterValue(cmd, "O_NIVEL_P").ToString();
                employee.CenterNumber = db.GetParameterValue(cmd, "O_CENTRO") == DBNull.Value ? 0 : Convert.ToInt32(db.GetParameterValue(cmd, "O_CENTRO"));
                employee.DepartmentNumber = db.GetParameterValue(cmd, "O_DEPTO") == DBNull.Value ? 0 : Convert.ToInt32(db.GetParameterValue(cmd, "O_DEPTO"));
                employee.DepartmentDescription = db.GetParameterValue(cmd, "O_DDEPTO").ToString();
                employee.EmployeeYear = db.GetParameterValue(cmd, "O_AEMP") == DBNull.Value ? 0 : Convert.ToInt32(db.GetParameterValue(cmd, "O_AEMP"));
                employee.EmployeeDay = db.GetParameterValue(cmd, "O_DEMP") == DBNull.Value ? 0 : Convert.ToInt32(db.GetParameterValue(cmd, "O_DEMP"));
                employee.FirstName = db.GetParameterValue(cmd, "O_NOMBRE").ToString();
                employee.LastName = db.GetParameterValue(cmd, "O_APPAT").ToString();
                employee.LastName2 = db.GetParameterValue(cmd, "O_APMAT").ToString();
                employee.Regime = db.GetParameterValue(cmd, "O_RC").ToString();
                employee.Organism = db.GetParameterValue(cmd, "O_ORGANISMO").ToString();
                employee.IsValid = db.GetParameterValue(cmd, "O_VALIDO") == DBNull.Value ? false : !Convert.ToBoolean(db.GetParameterValue(cmd, "O_VALIDO"));
                employee.DateFinish = db.GetParameterValue(cmd, "O_FEC_RPROY").ToString();
                employee.OrganismDescription = db.GetParameterValue(cmd, "O_DESC_ORG").ToString();
            }
            return employee;
        }
        catch (Exception ex)
        {
            return null;
        }           
    }

不幸的是,我没有10张发布图片的声誉。

最大的问题是,为什么ODP.NET可以很好地与企业库一起使用,但不能使用本来可以更好的本机代码。我做错了吗?

1 个答案:

答案 0 :(得分:0)

我对Mananged ODP.NET没有太多经验,但在较旧的ODP:NET中你必须指定最大值。返回值的长度,即它应该是这样的:

myOracleCmd.Parameters.Add("O_APMAT", OracleDbType.Varchar2, ParameterDirection.Output);
myOracleCmd.Parameters["O_APMAT"].Size = 1000;

或者您可以将它写在一行:

myOracleCmd.Parameters.Add("O_APMAT", OracleDbType.Varchar2, 1000, null, ParameterDirection.Output);

那么也许您还需要指定DbType参数,即

cmyOracleCmdmd.Parameters["O_APMAT"].DbType = DbType.String;

在这里,您可以看到DbType与OracleDbType的列表:C#: Oracle Data Type Equivalence with OracleDbType

然后一般注意:你的SP包含很多输出参数,也许只返回一个RefCursor并从这个光标读出属性而不是逐个定义每个输出参数。