将if / else转换为case

时间:2015-08-24 12:26:00

标签: sql-server stored-procedures case

我想知道是否有人能够并且愿意帮助我。 在我的Sql Server存储过程中,我有一系列if / else if语句,我想稍微帮助将其更改为case ... when ...然后我觉得它会更高效,看起来不那么混乱。 我并不是要求你为我做这只是一个简单的例子,让我能够理解它。

我的程序如下......

CREATE PROCEDURE [Blog].[ttc_BlogPosts]
@Status varchar(50) = '' ,
@EntryId int = '',
@Title nvarchar(max) = '',
@Added datetime = '',
@Updated datetime = '',
@Message nvarchar(max) = '',
@ImgId int = '',
@ImgUrl nvarchar(max) = ''

AS
BEGIN
     IF(@Status = 'Display')
       begin
            select Id, EntryTitle, Message, ImageUrl, DateAdded, LastEdited
            from Blog.BlogEntry
            order by DateAdded desc
       end

     else if(@Status = 'AddPost')
            begin

                insert into Blog.BlogEntry (EntryTitle, Message, DateAdded, ImageUrl)
                values (@Title, @Message, GETDATE(), @ImgUrl)   
            end
          else if(@Status = 'DisplayPost')
                 begin
                      select EntryTitle, DateAdded, LastEdited, Message, ImageUrl
                      from Blog.BlogEntry
                      where Id = @EntryId
                  end
               else if(@Status = 'UpdatePost')
                      begin
                          update Blog.BlogEntry
                          set EntryTitle = @Title, Message = @Message, LastEdited = GETDATE()
                          where Id = @EntryId
                      end 
                    else if(@Status = 'UpdatePostImage')
                           begin
                           update Blog.BlogEntry
                           set ImageUrl = @ImgUrl, LastEdited = GETDATE(), EntryTitle = @Title, Message = @Message
                           where Id = @EntryId
                        end
                     else if(@Status = 'DeletePost')
                         begin
                              delete from Blog.BlogEntry
                              where Id = @EntryId 
                          end
          END

你们愿意提供的任何帮助都将非常感激。如果需要任何进一步的细节,请不要犹豫,给我一个喊叫;)

3 个答案:

答案 0 :(得分:1)

在搜索过的CASE中使用M.Ali解决方案来比较可读性问题。

还添加了addtional @status验证

CREATE PROCEDURE [Blog].[ttc_BlogPosts]
     @Status     varchar(50)   = '' ,
     @EntryId    int           = NULL,  
     @Title      nvarchar(max) = '',
     @Added      datetime      = NULL,    
     @Updated    datetime      = NULL,
     @Message    nvarchar(max) = '',
     @ImgId      int           = NULL,
     @ImgUrl     nvarchar(max) = ''
 AS
 BEGIN
 SET NOCOUNT ON;

 DECLARE @Sql NVARCHAR(MAX);

-- A validate check since your else..if statement don't handle this case
IF (@Status = '' AND @Status NOT IN ('Display', 'DisplayPost', ...))
BEGIN
   RAISERROR('Provide value for @Status variable. Allowed values (Display, ...)',16,1)
   RETURN
END

SELECT @sql = CASE @status 
    WHEN 'Display' THEN
        N'select Id, EntryTitle, Message, ImageUrl, DateAdded, LastEdited
        from Blog.BlogEntry
        order by DateAdded desc'

    WHEN 'AddPost' THEN
        N'insert into Blog.BlogEntry (EntryTitle, Message, DateAdded, ImageUrl)
        values (@Title, @Message, GETDATE(), @ImgUrl)'   

    WHEN 'DisplayPost' THEN
        N'select EntryTitle, DateAdded, LastEdited, Message, ImageUrl
        from Blog.BlogEntry
        where Id = @EntryId'

    WHEN 'UpdatePost' THEN
        N'update Blog.BlogEntry
        set EntryTitle = @Title, Message = @Message, LastEdited = GETDATE()
        where Id = @EntryId'

    WHEN 'UpdatePostImage' THEN
        N'update Blog.BlogEntry
        set ImageUrl = @ImgUrl, LastEdited = GETDATE(), EntryTitle = @Title, Message = @Message
        where Id = @EntryId'

    WHEN 'DeletePost' THEN
        N'delete from Blog.BlogEntry
        where Id = @EntryId'
   END

EXEC [dbo].[sp_executesql] @Sql 
              ,N'@Status varchar(50),@EntryId int, @Title nvarchar(max), @Added datetime, 
                @Updated datetime, @Message nvarchar(max), @ImgId int, @ImgUrl nvarchar(max)'
              ,@Status 
              ,@EntryId 
              ,@Title 
              ,@Added
              ,@Updated 
              ,@Message 
              ,@ImgId 
              ,@ImgUrl 
END

答案 1 :(得分:0)

在SQL中,IF / ELSE提供与CASE / WHEN完全不同的功能,两者很少可以互换。

IF / ELSE可用于控制流程:

IF This
  DO THAT
ELSE
  DO Something else

CASE / WHEN返回单个值,无法控制流量。

SET @MyValue = CASE 
  WHEN [Color] = 'Red' THEN 1
  ELSE 0
END

由于您使用IF / ELSE来控制流量,因此您的代码不适合CASE / WHEN。

答案 2 :(得分:0)

这会奏效。将IF .. ELSE简单转换为CASE .. ELSE ... END

CREATE PROCEDURE [Blog].[ttc_BlogPosts]
@Status varchar(50) = '' ,
@EntryId int = '',
@Title nvarchar(max) = '',
@Added datetime = '',
@Updated datetime = '',
@Message nvarchar(max) = '',
@ImgId int = '',
@ImgUrl nvarchar(max) = ''

AS
BEGIN
     CASE WHEN(@Status = 'Display')
        THEN
            select Id, EntryTitle, Message, ImageUrl, DateAdded, LastEdited
            from Blog.BlogEntry
            order by DateAdded desc


        ELSE (CASE WHEN(@Status = 'AddPost')
              THEN

                insert into Blog.BlogEntry (EntryTitle, Message, DateAdded, ImageUrl)
                values (@Title, @Message, GETDATE(), @ImgUrl)   

              ELSE (CASE WHEN(@Status = 'DisplayPost')
                     THEN
                          select EntryTitle, DateAdded, LastEdited, Message, ImageUrl
                          from Blog.BlogEntry
                          where Id = @EntryId

                   ELSE (CASE WHEN(@Status = 'UpdatePost')
                          THEN
                              update Blog.BlogEntry
                              set EntryTitle = @Title, Message = @Message, LastEdited = GETDATE()
                              where Id = @EntryId

                        ELSE (CASE WHEN(@Status = 'UpdatePostImage')
                               THEN
                               update Blog.BlogEntry
                               set ImageUrl = @ImgUrl, LastEdited = GETDATE(), EntryTitle = @Title, Message = @Message
                               where Id = @EntryId

                               ELSE (CASE WHEN(@Status = 'DeletePost')
                                 THEN
                                      delete from Blog.BlogEntry
                                      where Id = @EntryId 
                                  END)
                               END)
                         END)
                     END)
                END)
            END
END