【问题标题】:Handle NULL values when reading through OracleDataReader?通过 OracleDataReader 读取时处理 NULL 值?
【发布时间】:2014-11-19 09:48:10
【问题描述】:

我正在开发我的第一个 ASP.Net 应用程序,并且似乎遇到了很多障碍(主要是 WinForms 的背景,我最近有一个 MVC5 项目)。

我使用OracleCommand 成功建立了我的数据库连接并执行了我的查询,但是当我尝试通读这些行时,我在odr.GetDecimal(1) 的第二行得到一个Column contains NULL value。有人知道在通过 OracleDataReader 读取时如何处理空值吗?

下面是我的代码:

        List<YearsOfService> yearsOfService = new List<YearsOfService>();
        string SQL = "SELECT SCHOOL_YEAR as YEAR, " +
                            "TOTAL_SERVICE_CREDIT as ServiceCredited, " +
                            "RETIREMENT_SALARY as Salary, " +
                            "SOURCE_VALUE as CoveredEmployer " +
                     "FROM " + Schema + ".RANDOM_ORACLE_TABLE a " +
                     "WHERE MEMBER_ACCOUNT_ID = :memberAccountId";

        DbConnection dbc = new DbConnection();
        OracleCommand cmd = dbc.GetCommand(SQL);
        cmd.Parameters.Add(new OracleParameter("memberAccountId", memberAccountId));
        OracleDataReader odr = cmd.ExecuteReader();

        int counter = 0;
        if (odr.HasRows)
        {
            while (odr.Read())
            {
                YearsOfService yos = new YearsOfService();
                yos.Year = odr.GetInt16(0);
                yos.ServiceCredited = odr.GetDecimal(1); // Error on Second Pass

                yos.Salary = odr.GetDecimal(2);

                yos.CoveredEmployer = odr.GetString(3);

                yearsOfService.Add(yos);
                counter++;
            }
        }

        return yearsOfService;
    }

我曾想过对 NULL 进行简单的检查,如果是这样,用 0 替换(因为期望 Decimal 值)将适用于以下内容,但没有运气。同样的错误:yos.ServiceCredited = Convert.IsDBNull(odr.GetDecimal(1)) ? 0 : odr.GetDecimal(1);

完整的错误是:

Oracle.DataAccess.dll 中出现“System.InvalidCastException”类型的异常,但未在用户代码中处理

附加信息:列包含 NULL 数据

我已确认返回的 2 行格式如下:

Year|CreditedService|Salary  |CoveredEmployer
2013|0.70128        |34949.66|ER
2014|NULL           | 2213.99|NULL

有人对如何最好地进行操作有建议吗?通过我的 OracleDataReader 读取时,我应该如何处理接收到 NULL 值?

【问题讨论】:

  • 只是对这一行感到好奇yos.ServiceCredited = odr.GetDecimal(1); 你为什么不按名称引用字段并在分配值之前检查它的值..? Look up Null Coalesce
  • 我没用过OracleDataReader,但我猜你需要检查odr.GetValue(1)是否为NULL而不是odr.GetDecimal(1)
  • 检查 odr.GetValue(0) != DBNull.Value
  • 另一种选择是合并 SQL 中的值。
  • @DJKRAZE,不确定我是否理解您的意思。不过会查找 Coalesce。 @juharr:我试过了,但是我得到了一个错误,因为yos.ServiceCredited 期望Decimal 值,而不仅仅是来自GetValue()object。 @Syed:试过了,没有运气,同样的错误。

标签: c# asp.net oracle null datareader


【解决方案1】:
yos.ServiceCredited = odr.IsDBNull(1) ? 0 : odr.GetDecimal(1);

OracleDataReader 提供了一个IsDBNull() 方法。

GetDecimal() 上的文档要求我们这样做

在调用此方法之前调用 IsDBNull 以检查空值。

【讨论】:

  • 感谢 Abhi,这成功了!我之前尝试过使用IsDBNull() 方法,但我执行不正确。以前我想我尝试过类似yos.ServiceCredited = Convert.IsDBNull(odr.GetDecimal(1)) 的东西。这是我第一次使用OracleDataReader,我对它如何使用不同的Get() 进行“列”引用没有经验。感谢您的帮助!
  • 感谢您。其他任何人都认为客户端必须进行这样的预检查调用以在您阅读之前确定该值是否为 Null 是绝对疯狂的吗?为什么GetDecimal() (etc) 不像其他所有数据库驱动程序一样只返回 Null 值?看起来很疯狂
  • @Black 我想这就是我们使用 Oracle 得到的结果?
  • @Black 因为 Decimal 值不能为空。如果该方法能够按照您的描述返回 null,那么您必须始终检查结果是否为 null,以便将其分配给 Decimal。
猜你喜欢
  • 1970-01-01
  • 2013-10-10
  • 1970-01-01
  • 2021-02-03
  • 2016-09-18
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多