在整个存储过程中重用条件?

时间:2019-04-03 06:47:33

标签: sql-server

我创建了一个存储过程,该存储过程从多个选择查询返回记录。

请参阅以下查询:

DECLARE @UserId UNIQUEIDENTIFIER = '96105876-AB55-4D28-A8DD-6BFEC9D38EF8'

SELECT 
    CD.[Name],
    CD.[ASIN],
    CD.[Category],
    CD.[Quantity],
    CD.[Total],
    CD.[Weight]
FROM CartDetails CD
INNER JOIN Cart C ON C.Id = CD.CartId 
INNER JOIN Users U ON U.Id = C.UserId
WHERE U.Id = @UserId AND U.Active = 1 AND U.Deleted = 0

SELECT  
    DCC.DiscountAmount, 
    DCC.DiscountCouponId
FROM DiscountCouponConsumed DCC
INNER JOIN Users U ON U.Id = DCC.UserId
WHERE U.Id = @UserId AND U.Active = 1 AND U.Deleted = 0

在这里,我在where条件中编写了相同的查询(始终保持相同)。现在我的问题是,我们可以一次编写一次where查询并将其用于每个select语句吗?

4 个答案:

答案 0 :(得分:2)

您可以将有效的用户ID存储在临时表中,该表根据您的常见where子句填充。您可以将这种方法扩展到任意多个查询。

DECLARE @UserId UNIQUEIDENTIFIER = '96105876-AB55-4D28-A8DD-6BFEC9D38EF8';

declare @User table (id uniqueidentifier);

insert into @User (id)
  select id
  from Users U
  where U.Id = @UserId AND U.Active = 1 AND U.Deleted = 0;

SELECT 
    CD.[Name],
    CD.[ASIN],
    CD.[Category],
    CD.[Quantity],
    CD.[Total],
    CD.[Weight]
FROM CartDetails CD
INNER JOIN Cart C ON C.Id = CD.CartId 
INNER JOIN Users U ON U.Id = C.UserId
--WHERE U.Id = @UserId AND U.Active = 1 AND U.Deleted = 0
where U.id in (select id from @User);

SELECT  
  DCC.DiscountAmount,
  DCC.DiscountCouponId
FROM DiscountCouponConsumed DCC
INNER JOIN Users U ON U.Id = DCC.UserId
--WHERE U.Id = @UserId AND U.Active = 1 AND U.Deleted = 0
where U.id in (select id from @User);

答案 1 :(得分:1)

如果您有单独的select语句,它们之间没有任何关系,那么这可能会对您有所帮助。在执行选择查询之前,在单独的变量中准备选择查询和Where查询,并将它们连接在一起。

DECLARE @UserId UNIQUEIDENTIFIER = '96105876-AB55-4D28-A8DD-6BFEC9D38EF8'

DECLARE @Query NVARCHAR(MAX) , @SelectQuery NVARCHAR(MAX), @WhereQuery NVARCHAR(MAX)

SET @WhereQuery = 'WHERE U.Id = @UserId AND U.Active = 1 AND U.Deleted = 0'

 -- Query 1 

SET @SelectQuery =
'SELECT 
    CD.[Name],
    CD.[ASIN],
    CD.[Category],
    CD.[Quantity],
    CD.[Total],
    CD.[Weight]
FROM CartDetails CD
INNER JOIN Cart C ON C.Id = CD.CartId 
INNER JOIN Users U ON U.Id = C.UserId'

SET @Query = @SelectQuery + @WhereQuery

EXEC (@Query)


--- Query 2

SET @Query = NULL 

SET @SelectQuery = NULL

SET @SelectQuery ='
SELECT  
    DCC.DiscountAmount, 
    DCC.DiscountCouponId
FROM DiscountCouponConsumed DCC
INNER JOIN Users U ON U.Id = DCC.UserId '

SET @Query = @SelectQuery + @WhereQuery

EXEC (@Query)

答案 2 :(得分:0)

接近Dales答案,但加入@Users。

DECLARE @UserId UNIQUEIDENTIFIER = '96105876-AB55-4D28-A8DD-6BFEC9D38EF8';

DECLARE @Users TABLE
(
    Id INT,
    Active BIT,
    Deleted BIT
);

INSERT INTO @Users
(
    Id,
    Active,
    Deleted
)
SELECT Id,
       Active,
       Deleted
FROM Users
WHERE U.Id = @UserId
      AND U.Active = 1
      AND U.Deleted = 0;

SELECT CD.Name,
       CD.ASIN,
       CD.Category,
       CD.Quantity,
       CD.Total,
       CD.Weight
FROM CartDetails CD
    INNER JOIN Cart C
        ON C.Id = CD.CartId
    INNER JOIN @Users U
        ON U.Id = C.UserId;

SELECT DCC.DiscountAmount,
       DCC.DiscountCouponId
FROM DiscountCouponConsumed DCC
    INNER JOIN @Users U
        ON U.Id = DCC.UserId;

答案 3 :(得分:0)

@MarcinJ在评论中提供了最简单的答案,我认为值得回答。

  

如果您始终以这种方式过滤用户记录,只需运行查询   检查用户是否处于活动状态并且在开始时未将其删除   您的存储过程,如果不符合您的条件,请重置   @UserId设置为NULL,以便其他任何查询都不会产生结果

即在proc的顶部具有以下代码:

select @UserId = case when exists (
    select 1
    from Users U
    where U.Id = @UserId AND U.Active = 1 AND U.Deleted = 0
  ) then @UserId else null end;