Страницы

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

вторник, 7 мая 2019 г.

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

Есть у меня функция
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)


Ответ

Как-то так:
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
Да, может быть сложнее в построении (когда много параметров), но может оказаться выгоднее для исполнения.

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

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