Почему этот запрос ADO.NET не дает результатов? - PullRequest
1 голос
/ 13 июня 2019

У меня есть следующий код, который выполняет оператор 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 Я могу перехватить SQL, отправленный в базу данных, но только один раз профилировщик предоставил значение для параметра :ProjectId, и это было в нижнем регистре. Как будто он не дал результатов, но как только я применил UPPER к этому значению, я получил результат.

Похоже, мне нужно каким-то образом ввести свой параметр в верхний регистр, чтобы запрос работал, но я понятия не имею, как. Тем не менее, если я сделаю ToString().ToUpper() для projectId GUID, я получу ошибку привязки параметра.

ОЧЕНЬ ВАЖНО: Я попытался полностью удалить предложение where и больше не добавлять параметр, поэтому все строки в таблице должны быть возвращены, но результаты по-прежнему отсутствуют.

Ответы [ 2 ]

4 голосов
/ 21 июня 2019

Я не знаю, как, но превращение строки 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";
2 голосов
/ 20 июня 2019

Используя более общий подход, попробуйте следующее

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() для projectId GUID, я получу ошибку привязки параметра.

Ссылка Метод Guid.ToString

Спецификатор N форматирует его до 32 цифр: 00000000000000000000000000000000

Если формат не указан, по умолчанию используется формат D, который будет включать 32 цифры, разделенные дефисами.

00000000-0000-0000-0000-000000000000

Это объясняет вашу ошибку привязки.

...