2017-02-27 158 views
0

我是一个初学SQL的人,我试图运行下面的SP。将参数添加到where子句sql

DECLARE @stringStatus varchar(100) 

--Check for status value 
IF @Status is NULL 
BEGIN 
    set @stringStatus = '' 
END 
ELSE 
BEGIN 
    set @stringStatus = ' and ps.Status = ' + CAST(@Status as varchar) 
END 

select * from Projects p 
    join projectstatus ps on p.pid = ps.pid 
    where ps.Category = isnull(@Category, p.Category) + @stringStatus 

的上述目的是如果@Status is NULL得到的所有行,并以过滤行中,如果有一个参数被分配给@Status
@Category(VARCHAR)和@Status(INT)是IN paramateres

能正常工作时@Status为NULL,即,我得到的所有记录。但是如果我传递一个参数,例如@Status = 2,那么即使有几条记录可用,执行也不会返回任何行。

首先,我如何得到我想要的结果?其次,有没有更好的方法来做到这一点,而不是如果条件块?

回答

1

其实,你的结果是

select * from something where ps.Category ='some string, containing and ps.Status= inside' 

所以空行集预期的结果。
你想是这样的(希望状态数量,而不是字符串)

select * from Projects p 
    join projectstatus ps on p.pid = ps.pid 
    where ps.Category = isnull(@Category, p.Category) and 
    (@Status is NULL OR ps.Status = @Status) 

好,这里是不信任的测试:-)

declare @projects table 
(
    pid int, 
    name nvarchar(20), 
    category int 
); 

declare @projectstatus table 
(
    pid int, 
    Category int, 
    status int 
); 

insert into @projects values 
(1,'Project 1', 1),(2,'Project 2',1),(3,'Project 3',1),(4,'Project 4',1),(5,'Project 5',1); 

insert into @projectstatus values 
(1,1,1),(2,1,2),(3,1,3),(4,1,2),(5,1,NULL); 


declare @Category int =null; 
declare @Status int; 

--first of all, do not understand, what is the logic with category 
--category in one table should be the same, than in other table or specified? 
--ok, you said with category everything is ok, do not test category, test status 

--test with null 
set @Status=null 


select * from @Projects p 
    join @projectstatus ps on p.pid = ps.pid 
    where ps.Category = isnull(@Category, p.Category) and 
    (@Status is NULL OR ps.Status = @Status) 

--test with existing status  
set @Status=1 
select * from @Projects p 
    join @projectstatus ps on p.pid = ps.pid 
    where ps.Category = isnull(@Category, p.Category) and 
    (@Status is NULL OR ps.Status = @Status) 

--test with not existing status  
set @Status=10 
select * from @Projects p 
    join @projectstatus ps on p.pid = ps.pid 
    where ps.Category = isnull(@Category, p.Category) and 
    (@Status is NULL OR ps.Status = @Status) 
+0

(@Status为空或PS .Status = @Status)总是会返回完整列表。它永远不会过滤。 –

+0

不同意。例如@Status = 1,将返回状态为1的行,并且不显示状态为2的行。我甚至可以给出临时表 – vitalygolub

+0

的示例我诚挚的道歉。我误读了第一部分作为ps.status –

0

您可以在下面的方式进行简单的放条件您想要的结果

--Check for status value 
IF @Status is NULL 
    BEGIN 
    select * from Projects p 
    join projectstatus ps on p.pid = ps.pid 
    where ps.Category = isnull(@Category, p.Category) 
    END 
ELSE 
    BEGIN 
    select * from Projects p 
    join projectstatus ps on p.pid = ps.pid 
    where ps.Category = isnull(@Category, p.Category) + @stringStatus 
    END 

感谢