У меня есть панель поиска с различными параметрами поиска, я хочу, чтобы запрос SQL выполнял поиск только с заполненными текстовыми полями.
Я сделал простую SP, которая отлично работала, когда у меня была панель поиска только с двумя параметрами поиска (имя и код) с использованием операторов if (не лучшая практика). Однако теперь, когда у меня были панели поиска с 4-5 элементами, операторы IF не кажутся лучшей практикой для производительности.
Это процедура, которую я сделал для случая, когда у меня было только 2 варианта поиска:
@Code_client nvarchar(50),
@Intitule_client varchar(100)
as
IF (@Code_client is not NULL AND @Code_client!='')
BEGIN
IF (@Intitule_client IS not NULL AND @Intitule_client!='')
select * from Clients where Code_client=@Code_client and Intitule_client=@Intitule_client
ELSE
select * from Clients where Code_client=@Code_client
END
ELSE IF (@Intitule_client is not null AND @Intitule_client!='')
BEGIN
select * from Clients where Intitule_client=@Intitule_client
END
Но для этого случая у меня есть 4 варианта поиска:
<div id = "chercher_employe" class = "Rechercher">
<ul>
<li>
<asp:TextBox runat = "server" ID = "chercher_employe_Nom" CssClass = "Input" placeholder = "Nom employe"></asp:TextBox>
</li>
<li>
<asp:TextBox runat = "server" ID = "chercher_employe_Departement" CssClass = "Input" placeholder = "Departement"></asp:TextBox>
</li>
<li>
<asp:TextBox runat = "server" ID = "chercher_employe_occupation" CssClass = "Input" placeholder = "Occupation"></asp:TextBox>
</li>
<li>
<asp:TextBox runat = "server" ID = "chercher_employe_IntituleProfil" CssClass = "Input" placeholder = "Profil"></asp:TextBox>
</li>
<li>
<asp:LinkButton runat = "server" CssClass = "button"> <i class = "fas fa-search"></i> </asp:LinkButton>
</li>
</ul>
</div>
Я не могу найти другого способа, кроме использования операторов if с C# или SQL, какие-либо предложения, пожалуйста?
select * from Clients where (Code_client=@Code_client or @Code_client is null) and (Intitule_client=@Intitule_client or @Intitule_client is null) and...
Есть несколько способов сделать это со статическим SQL, для начала это. Однако остальную часть этой статьи тоже стоит прочитать, потому что есть некоторые подводные камни производительности, которые следует учитывать при таких динамических запросах.
Я предлагаю взглянуть на запросы на кухонную мойку и Универсальные запросы. Динамический SQL, скорее всего, подойдет, но если эта логика контролируется со стороны приложения, вам просто нужно правильно построить оператор SQL и не включать предложения, в которых параметр не имеет значения.
Оператор if — не что иное, как логическое следствие
a -> b
если а то б
который также может быть записан как
!a or b
не а и не б
Итак, ваше утверждение if
IF (@Intitule_client IS not NULL AND @Intitule_client!='')
select * from Clients where Code_client=@Code_client and Intitule_client=@Intitule_client
можно перевести на (используя законы Де Моргана для упрощения двойного отрицания (not(a or b) <=> not(a) and not(b)
)
SELECT *
FROM Clients
WHERE (@Intitule_client IS NULL OR @Intitule_client = '' OR Intitule_client = @Intitule_client) AND Code_client = @Code_client
Затем вы можете использовать этот шаблон для создания более сложных запросов.
Будьте осторожны, так как это, скорее всего, приведет к плохим кэшированным планам запросов.
Предложение @Larnu и @jarlh сработало для меня лучше всего. Эта ссылка объясняет это очень хорошо: https://blogs.sentryone.com/aaronbertrand/backtobasics-updated-kitchen-sink-example/
Спасибо всем за ответы, спасибо :)
(Пожалуйста, запишите свой ответ здесь, чтобы я мог принять его, если у кого-то была такая же проблема ^^)
у вас может быть коллекция текстовых полей, затем выберите все, где !string.isnullorempty, затем для каждого выполните соответствующий запрос или соедините их, если вы отправляете sproc