Допустим, у меня есть таблица «Student» со следующими столбцами: FirstName, LastName, Grade. Теперь допустим, что у меня есть процедура getStudents, в которую можно передать список оценок, разделенных запятыми, из которых можно выбирать. Это выглядит примерно так:
CREATE PROCEDURE [dbo].[getStudents] (
@GradeList VARCHAR(MAX)
)
AS
BEGIN
--Declare temporary table for grades
CREATE TABLE #Grades (Grade varchar(50))
--Insert the grades from @GradeList parameter into the temp table
INSERT INTO
#Grades
SELECT value AS Grade
FROM
--This is a function that will split the comma delimited list and return the values
[dbo].[SplitValues] (@GradeList)
--Select all students that are in the grades provided
SELECT
FirstName,
LastName
FROM
Student
WHERE
Grade IN (SELECT Grade FROM #Grades)
END
Это все работает как задумано. Но сейчас мы хотим сделать @GradeList необязательным параметром. Если его значение равно NULL, мы хотим вернуть всех студентов. В этом упрощенном примере я бы просто сделал оператор IF, но на самом деле мы хотим иметь несколько необязательных параметров, поэтому он должен быть частью одного и того же оператора SELECT. Я смог заставить это работать со следующими логинами c:
CREATE PROCEDURE [dbo].[getStudents] (
@GradeList VARCHAR(MAX) = NULL
)
AS
BEGIN
--Declare temporary table for grades
CREATE TABLE #Grades (Grade varchar(50))
--Insert list of grades into a temporary table
IF @GradeList IS NULL
BEGIN
--No grades provided, select all possible values for Grade into temp table
INSERT INTO
#Grades
SELECT DISTINCT
Grade
FROM
Student
END
ELSE
BEGIN
--Insert the grades from @GradeList parameter into the temp table
INSERT INTO
#Grades
SELECT value AS Grade
FROM
--This is a function that will split the comma delimited list and return the values
[dbo].[SplitValues] (@GradeList)
END
--Select all students that are in the grades provided
SELECT
FirstName,
LastName
FROM
Student
WHERE
Grade IN (SELECT Grade FROM #Grades)
END
Так что, если ничего не передается, я просто добавляю все возможные значения Grade во временную таблицу #Grades. Функционально это работает и делает то, что мы хотим. Однако, поскольку здесь мы имеем дело с большими таблицами, это добавило огромные накладные расходы к процедуре (теперь она занимает до минуты, прежде чем это было ~ 1-2 секунды). Есть ли способ, чтобы условие в предложении WHERE зависело от того, существует ли значение для @GradeList?