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