То, как вы сформулировали запрос в настоящее время и ввод динамических списков параметров, подразумевает для меня, что вы существенно строите запрос в памяти и выполняете его, и в этом случае вам, вероятно, лучше использовать клиент язык, который строит запрос так, чтобы он в любом случае просто вставлял элементы. Вы не можете вставить список напрямую через параметр или переменную SQL на любом диалекте, который я знаю, поэтому я не стал бы пытаться делать все возможное, чтобы избежать того, что вам в основном нужно делать.
Тем не менее, если вы хотите использовать более постоянную структуру запроса при компиляции этого - при условии, что у вас есть таблица CategoryBdocs с полем CategoryBdocID, объявленным как INT Identity (1,1), тогда вы можете получить что-то работая в соответствии с текущим запросом, выполнив
select *
from library
where libraryID in
(select distinct libraryID from categoryAdocs where categoryAdocID in (4))
or LibraryID in
(select distinct libraryID from categoryBdocs where categoryBdocID in (-1))
и объедините список категорий B после -1 - это всегда ничего не вернет, так что это безопасно. Если Year не входит в список, вы можете использовать его как необязательный параметр, используя что-то вроде
or Year in (COALESCE(2004, Year))
и когда вместо 2004 года вышло NULL, оно совпадало с собой и возвращалось. Однако вы не можете сделать это со списком, и я не могу придумать, как сделать это в SQL с помощью необязательного списка.
Все это основано на предположении, что вы строите запрос в памяти и выполняете его, хотя это то, что вы, похоже, делаете. Вы сказали, что вам не нравится это делать, и я согласен - это не идеально эффективно, и передача списка для объединения в запрос упрощает доступ к SQL-инъекциям.
Чтобы обойти это, я бы предложил обернуть это в сохраненный процесс. Если затем вы передаете строки с разделителями, содержащие ваши идентификаторы для каждого из трех списков, вы можете разделить их на таблицы с отдельными значениями, объединив их с таблицей чисел / счетчиков (подробности в другом из моих ответов - Выбор SQL из данных в запросе где эти данные еще не в базе данных? ). Отсюда вы можете написать это в соответствии с
SELECT L.*
FROM Library L
INNER JOIN CategoryADocs A
ON L.LibraryID=A.LibraryID
INNER JOIN ([CategoryA Derived table]) ADocs
ON A.CategoryAdocID=ADocs.CategoryADocID
LEFT JOIN (SELECT B.* FROM CategoryBDocs B
INNER JOIN [CategoryB Derived Table] BDocs
ON B.CategoryBdocID=BDocs.CategoryBDocID) B
ON L.LibraryID=B.LibraryID
LEFT JOIN ([Years Derived table]) Y
ON L.Year=Y.Year
WHERE
COALESCE(B.LibraryID,-1)=CASE WHEN Len(@BIDs) > 1 THEN B.LibraryID ELSE -1
AND COALESCE(L.Year,-1)=CASE WHEN Len(@Years) > 1 THEN L.Year ELSE -1
То, что я признаю, длиннее и сложнее, но позволяет вам поместить всю логику в SQL без необходимости динамического построения запросов. Если вы думаете, что это стоит сложности, я оставлю до вас!