将 if/else 转换为大小写
convert if/else to case
我想知道是否有人能够并愿意帮助我。
在我的 Sql 服务器存储过程中,我有一系列 if / else if 语句,我需要一些帮助将其更改为 case...when...then,因为我觉得它会更有效率并且看起来少凌乱。
我并不是要你为我做这件事,只是一个简单的例子,让我能够理解它。
我的存储过程如下...
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
非常感谢你们愿意提供的任何帮助。如果需要任何进一步的详细信息,请随时告诉我 ;)
担心你的代码看起来如何,我会更担心这段代码的执行方式,你会在这个过程中遇到巨大的参数嗅探问题,为了避免它你需要动态 sql 这样sql 服务器可以缓存此过程的参数化执行计划,而不是拥有一个执行计划并尝试使用相同的计划执行每个查询。
您还有一些变量值设置为无效值,例如 Int 变量被设置为空字符串 ''
日期时间变量也被设置为空字符串,请看下面,此过程应该可以帮助您更好的性能。
CREATE PROCEDURE [Blog].[ttc_BlogPosts]
@Status varchar(50) = '' ,
@EntryId int = NULL, --< can't set int variable to empty string
@Title nvarchar(max) = '',
@Added datetime = NULL, --< can't set Date/DateTime variable to empty string
@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 = '')
BEGIN
RAISERROR('Provide value for @Status variable',16,1)
RETURN
END
IF(@Status = 'Display')
begin
SET @Sql = N'
select Id, EntryTitle, Message, ImageUrl, DateAdded, LastEdited
from Blog.BlogEntry
order by DateAdded desc'
end
else if(@Status = 'AddPost')
begin
SET @Sql = N'
insert into Blog.BlogEntry (EntryTitle, Message, DateAdded, ImageUrl)
values (@Title, @Message, GETDATE(), @ImgUrl)'
end
else if(@Status = 'DisplayPost')
begin
SET @Sql = N'
select EntryTitle, DateAdded, LastEdited, Message, ImageUrl
from Blog.BlogEntry
where Id = @EntryId'
end
else if(@Status = 'UpdatePost')
begin
SET @Sql = N'
update Blog.BlogEntry
set EntryTitle = @Title, Message = @Message, LastEdited = GETDATE()
where Id = @EntryId'
end
else if(@Status = 'UpdatePostImage')
begin
SET @Sql = N'
update Blog.BlogEntry
set ImageUrl = @ImgUrl, LastEdited = GETDATE(), EntryTitle = @Title, Message = @Message
where Id = @EntryId'
end
else if(@Status = 'DeletePost')
begin
SET @Sql = N'
delete from Blog.BlogEntry
where Id = @EntryId'
end
Exec 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
因此,本着
的精神
"just a quick example to enable me to get my head around it..."
你可以做动态 SQL.
DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = CASE
WHEN @Status = 'Display' THEN @SQL = 'select Id, EntryTitle, Message, ImageUrl, DateAdded, LastEdited from Blog.BlogEntry order by DateAdded desc'
WHEN @Status = 'DisplayPost' THEN ...
WHEN @Status = 'UpdatePost' THEN ...
WHEN @Status = 'UpdatePostImage' THEN ...
WHEN @Status = 'DeletePost' THEN ...
END
EXEC (@SQL)
您要 运行 的唯一问题是您需要将变量连接到您的语句中,如下所示
THEN @SQL = 'update Blog.BlogEntry set EntryTitle =''' + @Title + ''', Message =''' + @Message + ''', LastEdited = ''' + GETDATE() + ''' where Id = ''' @EntryId
在SQL中,IF/ELSE与CASE/WHEN的功能完全不同,两者很少可以互换。
IF/ELSE可用于控制流量:
IF This
DO THAT
ELSE
DO Something else
CASE/WHEN returns单个值,无法控制流量
SET @MyValue = CASE
WHEN [Color] = 'Red' THEN 1
ELSE 0
END
您的代码不适合 CASE/WHEN,因为您使用 IF/ELSE 来控制流程。
这会奏效。这是 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
使用 解决方案与搜索 CASE 比较可读性问题。
还添加了额外的@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
我想知道是否有人能够并愿意帮助我。 在我的 Sql 服务器存储过程中,我有一系列 if / else if 语句,我需要一些帮助将其更改为 case...when...then,因为我觉得它会更有效率并且看起来少凌乱。 我并不是要你为我做这件事,只是一个简单的例子,让我能够理解它。
我的存储过程如下...
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
非常感谢你们愿意提供的任何帮助。如果需要任何进一步的详细信息,请随时告诉我 ;)
担心你的代码看起来如何,我会更担心这段代码的执行方式,你会在这个过程中遇到巨大的参数嗅探问题,为了避免它你需要动态 sql 这样sql 服务器可以缓存此过程的参数化执行计划,而不是拥有一个执行计划并尝试使用相同的计划执行每个查询。
您还有一些变量值设置为无效值,例如 Int 变量被设置为空字符串 ''
日期时间变量也被设置为空字符串,请看下面,此过程应该可以帮助您更好的性能。
CREATE PROCEDURE [Blog].[ttc_BlogPosts]
@Status varchar(50) = '' ,
@EntryId int = NULL, --< can't set int variable to empty string
@Title nvarchar(max) = '',
@Added datetime = NULL, --< can't set Date/DateTime variable to empty string
@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 = '')
BEGIN
RAISERROR('Provide value for @Status variable',16,1)
RETURN
END
IF(@Status = 'Display')
begin
SET @Sql = N'
select Id, EntryTitle, Message, ImageUrl, DateAdded, LastEdited
from Blog.BlogEntry
order by DateAdded desc'
end
else if(@Status = 'AddPost')
begin
SET @Sql = N'
insert into Blog.BlogEntry (EntryTitle, Message, DateAdded, ImageUrl)
values (@Title, @Message, GETDATE(), @ImgUrl)'
end
else if(@Status = 'DisplayPost')
begin
SET @Sql = N'
select EntryTitle, DateAdded, LastEdited, Message, ImageUrl
from Blog.BlogEntry
where Id = @EntryId'
end
else if(@Status = 'UpdatePost')
begin
SET @Sql = N'
update Blog.BlogEntry
set EntryTitle = @Title, Message = @Message, LastEdited = GETDATE()
where Id = @EntryId'
end
else if(@Status = 'UpdatePostImage')
begin
SET @Sql = N'
update Blog.BlogEntry
set ImageUrl = @ImgUrl, LastEdited = GETDATE(), EntryTitle = @Title, Message = @Message
where Id = @EntryId'
end
else if(@Status = 'DeletePost')
begin
SET @Sql = N'
delete from Blog.BlogEntry
where Id = @EntryId'
end
Exec 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
因此,本着
的精神"just a quick example to enable me to get my head around it..."
你可以做动态 SQL.
DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = CASE
WHEN @Status = 'Display' THEN @SQL = 'select Id, EntryTitle, Message, ImageUrl, DateAdded, LastEdited from Blog.BlogEntry order by DateAdded desc'
WHEN @Status = 'DisplayPost' THEN ...
WHEN @Status = 'UpdatePost' THEN ...
WHEN @Status = 'UpdatePostImage' THEN ...
WHEN @Status = 'DeletePost' THEN ...
END
EXEC (@SQL)
您要 运行 的唯一问题是您需要将变量连接到您的语句中,如下所示
THEN @SQL = 'update Blog.BlogEntry set EntryTitle =''' + @Title + ''', Message =''' + @Message + ''', LastEdited = ''' + GETDATE() + ''' where Id = ''' @EntryId
在SQL中,IF/ELSE与CASE/WHEN的功能完全不同,两者很少可以互换。
IF/ELSE可用于控制流量:
IF This
DO THAT
ELSE
DO Something else
CASE/WHEN returns单个值,无法控制流量
SET @MyValue = CASE
WHEN [Color] = 'Red' THEN 1
ELSE 0
END
您的代码不适合 CASE/WHEN,因为您使用 IF/ELSE 来控制流程。
这会奏效。这是 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
使用
还添加了额外的@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