Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

Как передать запрос со значением параметра null

#sql #sql_server


Есть у меня функция

SqlCommand GetCommand(string value)
{
    var comm = new SqlCommand();
    comm.CommandText = "SELECT * FROM MyTable WHERE anyField = @param";
    comm.Parameters.Add("@param").Value = value;
    ****
}


А как быть со случаями, когда value передается null? Ведь язык TSQL не есть фильтр
вида anyField = null. Неужели переписывать на этот случай заново весь запрос, исправляя
на anyField is null? Просто параметров на самом деле много, и каждому предусматривать
значение null как-то не по христиански.

UPD:

Я сделал так... Еще не тестировал, но посмотрите, не чересчур ли это?

if (filters != null)
{
    var pCounter = 0;
    filtersPart = $" WHERE ({string.Join(" OR ", filters.Select(d => $"({string.Join("
AND ", d.Select(kv => kv.Value.Value != null ? (kv.Value.Key ? $"[{kv.Key}] = @param{++pCounter}"
: $"[{kv.Key}] LIKE @param{++pCounter}") : $"[{kv.Key}] is null"))})"))}) ";
    pCounter = 0;
    foreach(var d in filters)
        foreach(var kv in d)
            if (kv.Value.Value != null)
                res.Parameters.AddWithValue($"param{++pCounter}", kv.Value.Value);
}


filters тут это List>>, где List -
это список фильтров через OR, dictionary - это список фильтров через AND, где string
- это имя столбца, KeyValuePair - это значение столбца и булейное значение, указывающее,
четкое ли нужно совпадение (= @param) или похожее (LIKE @param)
    


Ответы

Ответ 1



Как-то так: SqlCommand GetCommand(string value) { var comm = new SqlCommand(); comm.CommandText = @" SELECT * FROM MyTable WHERE (anyField = @param or anyField is NULL and @param is NULL) -- and/or (другие условия)"; comm.Parameters.AddWithValue("@param", (object)value ?? DBNull.Value); ... } Можно comm.CommandText = "SELECT * FROM MyTable WHERE ISNULL(anyField, '') = ISNULL(@param, '')"; но это хуже в плане возможного использования индексов, т.к. будет потеряно sargability. Либо действительно динамический запрос. Если value != null то запрос один: SELECT * FROM MyTable WHERE anyField = @param а если value == null, то другой: SELECT * FROM MyTable WHERE anyField is NULL Да, может быть сложнее в построении (когда много параметров), но может оказаться выгоднее для исполнения.

Комментариев нет:

Отправить комментарий