Where子句中的SQL Server条件语句

时间:2017-11-23 10:52:12

标签: sql-server sql-server-2012

我需要编写一个SQL查询,根据提供的RoleId检索记录。

e.g。

  • 如果RoleId = 1那么_t1.CreatedBy = @LoginUserId。

对于其他RoleId,我希望来自表的所有记录在CreatedBy列上没有任何条件。

我按照我的要求提供样本查询。

SELECT _t1.*
FROM [dbo].[TblPassDetail] _t1 WITH (NOLOCK) 
INNER JOIN [dbo].[TblVisitor] _t2 WITH (NOLOCK) ON _t1.VisitorId = _t2.SrNo 
WHERE _t1.LocationId = @LocationId
  AND _t1.CreatedBy = (CASE WHEN @RoleId = 1 THEN @LoginUserId ELSE 0 END) 

问题是,如果提供的@RoleId为1,我将获得LoginUserId的所有记录,但如果@RoleId不是1,那么我没有得到任何记录SQL检查表中不存在的_t1.CreatedBy = 0的记录。

有关如何重写查询的任何建议吗?

3 个答案:

答案 0 :(得分:1)

您可以将WHERE子句的难点部分改写为:

@RoleId = 1 AND _t1.CreatedBy = @LoginUserId
OR
@RoleId <> 1

换句话说,如果RoleId1,则登录用户必须是创建者。但是对于其他RoleId值,对登录用户没有这种依赖性。以下是完整查询:

SELECT _t1.*
FROM [dbo].[TblPassDetail] _t1 WITH (NOLOCK) 
INNER JOIN [dbo].[TblVisitor] _t2 WITH (NOLOCK)
    ON _t1.VisitorId = _t2.SrNo 
WHERE
    _t1.LocationId = @LocationId AND
    (
        (@RoleId = 1 AND _t1.CreatedBy = @LoginUserId) OR
        @RoleId <> 1
    );

答案 1 :(得分:1)

实现此目的的一种方法是将CASE语句转换为OR

SELECT _t1.*
FROM [dbo].[TblPassDetail] _t1 WITH (NOLOCK) 
     INNER JOIN [dbo].[TblVisitor] _t2 WITH (NOLOCK) ON _t1.VisitorId = _t2.SrNo 
WHERE _t1.LocationId = @LocationId
      AND ( (_t1.CreatedBy = @LoginUserId AND @RoleID = 1) OR @RoleID <> 1)

另一种方式,解决方法如下,但由于使用了LIKE,您需要检查执行计划及其性能:

SELECT _t1.*
FROM [dbo].[TblPassDetail] _t1 WITH (NOLOCK) 
     INNER JOIN [dbo].[TblVisitor] _t2 WITH (NOLOCK) ON _t1.VisitorId = _t2.SrNo 
WHERE _t1.LocationId = @LocationId
AND _t1.CreatedBy LIKE (CASE WHEN @RoleId = 1 THEN @LoginUserId ELSE '%%' END)

答案 2 :(得分:0)

获取&lt;&gt;时的所有记录1

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/**").permitAll()
            .and()
            .oauth2Login();
}