比方说,我有一个名为“学生”的表格,其中包含以下列:名字,姓氏,成绩。现在,假设我有一个名为“ 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语句的一部分。我能够按照以下逻辑进行操作:
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是否有值?
答案 0 :(得分:2)
我想你想要
a + (a-b)/c*c
无需使用临时表来存储结果。您可以直接在查询中使用SELECT s.FirstName, s.LastName
FROM Student s
WHERE s.Grade IN (SELECT g.Grade FROM #Grades g) OR
@GradeList IS NULL;
。但是,如果您确实使用临时表,则最好充分利用它。将split_string()
定义为主键:
Grade
这为优化以后的查询提供了更多机会。