Начинът, по който сте формулирали заявката в момента и въвеждането на динамични списъци с параметри, за мен предполага, че изграждате заявката значително в паметта и я изпълнявате, в който случай вероятно е най-добре да използвате клиентския език, който изгражда заявката просто да пуснете елементите, когато така или иначе ги искате. Не можете да вмъкнете списък директно чрез 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 - това винаги няма да връща нищо, така че е безопасно. Ако Годината не влизаше като списък, можете да я накарате да работи като незадължителен параметър, като използвате нещо като
or Year in (COALESCE(2004, Year))
и когато излезе с NULL вместо 2004, щеше да съвпадне със себе си и да се върне. Въпреки това не можете да направите това със списък и не мога да измисля чист начин да го направя в 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, без да се нуждаете от динамично изграждане на заявки. Дали смятате, че си струва сложността, оставям на вас!
person
eftpotrm
schedule
06.04.2010