为什么此ADO.NET查询不返回结果?

时间:2019-06-13 09:27:41

标签: oracle ado.net oracle12c datareader

我有以下执行SQL语句并查找结果的代码。

var sql = @"select BOQ_IMPORT_ID "
          + "from ITIS_PRJ.PRJ_BOQ_IMPORT_HEADER "
          + "where PROJECT_ID = :Projectid "
          + "order by CREATED_ON desc "
          + "fetch first 1 row only";
using (var conn = new OracleConnection(ApplicationSettings.ConnectionString))
using (var cmd = new OracleCommand(sql, conn))
{
    conn.Open();
    cmd.Parameters.Add(LocalCreateParameterRaw("ProjectId", projectId));
    var reader = cmd.ExecuteReader();
    if (reader.Read())
    {
        byte[] buffer = new byte[16];
        reader.GetBytes(0, 0, buffer, 0, 16);
        var boqId = new Guid(buffer);
        return boqId;
    }

    return null;
}

LocalCreateParameterRaw声明为:

public static OracleParameter LocalCreateParameterRaw(string name, object value)
{
    OracleParameter oracleParameter = new OracleParameter();
    oracleParameter.ParameterName = name;
    oracleParameter.OracleDbType = OracleDbType.Raw;
    oracleParameter.Size = 16;
    oracleParameter.Value = value;
    return oracleParameter;
}

“ projectId”的基础类型为“ Guid”。

尽管表中仅存在一行,但if (reader.Read())始终求值为false。它通常应该只返回一行。

使用GI Oracle Profiler可以捕获发送到db的SQL,但事件探查器仅一次为:ProjectId参数提供了一个值,并且使用小写形式。像这样,它没有返回结果,但是一旦我将UPPER应用于该值,我就会得到结果。

看来我必须以某种方式将我的参数转换为大写字母才能使查询正常工作,但是我不知道该怎么做。但是,如果我在ToString().ToUpper() GUID上执行projectId,则会出现参数绑定错误。

非常重要: 我尝试完全删除where子句,并且不再添加参数,因此应该返回表中的所有行,但仍然没有结果。

2 个答案:

答案 0 :(得分:4)

我不知道如何,但是将SQL字符串变成逐字字符串(以@开头)会导致proc正常工作。因此,它不适用于:

var sql = @"SELECT BOQ_IMPORT_ID "
      + "FROM ITIS_PRJ.PRJ_BOQ_IMPORT_HEADER "
      + "WHERE PROJECT_ID = :projectid "
      + "ORDER BY CREATED_ON DESC "
      + "FETCH FIRST ROW ONLY";

但是,SQL Developer中的相同命令字符串将执行并返回结果。如下所示,当我使SQL字符串保持原状时,我得到结果。

var sql = @"select BOQ_IMPORT_ID 
            from ITIS_PRJ.PRJ_BOQ_IMPORT_HEADER 
            where PROJECT_ID = :ProjectId 
            order by CREATED_ON desc 
            fetch first 1 row only";

答案 1 :(得分:2)

使用更通用的方法,请尝试以下

var sql = "SELECT BOQ_IMPORT_ID "
      + "FROM ITIS_PRJ.PRJ_BOQ_IMPORT_HEADER "
      + "WHERE PROJECT_ID = :projectid "
      + "ORDER BY CREATED_ON DESC "
      + "FETCH FIRST ROW ONLY";
using (DbConnection conn = new OracleConnection(ApplicationSettings.ConnectionString))
using (DbCommand cmd = conn.CreateCommand()) {
    DbParameter parameter = cmd.CreateParameter();
    parameter.ParameterName = "projectid";
    parameter.Value = projectId.ToString("N").ToUpper(); //<-- NOTE FORMAT USED

    cmd.Parameters.Add(parameter);
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = sql;

    conn.Open();

    var reader = cmd.ExecuteReader();
    if (reader.Read()) {
        var boqId = new Guid((byte[])reader[0]);
        return boqId;
    }
    return null;
}
  

看来我必须以某种方式将我的参数转换为大写字母才能使查询正常工作,但是我不知道该怎么做。但是,如果我在ToString().ToUpper() GUID上执行projectId,则会出现参数绑定错误。

引用Guid.ToString Method

  

说明符N将其格式化为32位数字:00000000000000000000000000000000000000

如果未提供任何格式,则默认格式为D,其中将包含由连字符分隔的32位数字。

00000000-0000-0000-0000-000000000000

这将解释您的绑定错误。