在存储过程中使用CASE语句

时间:2018-10-24 08:51:39

标签: sql sql-server tsql stored-procedures

我有一个存储过程,它根据指定的输入参数调用其他存储过程。

外观如下:

CREATE PROCEDURE dbo.usp_SPCaller
@Input_Param1 NVARCHAR(100) = NULL,
@Input_Param2 NVARCHAR(100) = NULL

AS
BEGIN
SET NOCOUNT ON    

IF ((@Input_Param1 IS NOT NULL) AND (@Input_Param2 IS NOT NULL))
   BEGIN
       EXEC dbo.usp_SPWithParam1And2
   END 

IF ((@Input_Param1 IS NOT NULL) AND (@Input_Param2 IS NULL))
   BEGIN
       EXEC dbo.usp_SPWithParam1Only
   END

IF ((@Input_Param1 IS NULL) AND (@Input_Param2 IS NOT NULL))
   BEGIN
       EXEC dbo.usp_SPWithParam2Only
   END

IF ((@Input_Param1 IS NULL) AND (@Input_Param2 IS NULL))
   BEGIN
       EXEC dbo.usp_SPWithoutParam1And2
   END

在向我们的领导介绍此内容后,他建议我改用CASE STATEMENTS,因为使用IF STATEMENTS是个坏主意。

我尝试到处搜索如何以与上面相同的格式使用案例陈述,但无济于事。我发现的只是使用CASE STATEMENTS和UPDATE。

我的问题

如何以类似于上面的方式在SQL SERVER中使用CASE STATEMENTS?

4 个答案:

答案 0 :(得分:2)

尝试此代码。 在这里,我将要执行的过程名称存储在名为@sql的变量中,最后使用sp_executesql

执行此变量。
CREATE PROCEDURE dbo.usp_SPCaller 
@Input_Param1 NVARCHAR(100) = NULL,
@Input_Param2 NVARCHAR(100) = NULL

AS
BEGIN
SET NOCOUNT ON

DECLARE @sql AS NVARCHAR(MAX)

set @sql = case 
   when ((@Input_Param1 IS NOT NULL) AND (@Input_Param2 IS NOT NULL))
   then 'dbo.usp_SPWithParam1And2'

   when ((@Input_Param1 IS NOT NULL) AND (@Input_Param2 IS NULL))
   then 'dbo.usp_SPWithParam1Only'

   when((@Input_Param1 IS NULL) AND (@Input_Param2 IS NOT NULL))
   then 'dbo.usp_SPWithParam2Only'

   when ((@Input_Param1 IS NULL) AND (@Input_Param2 IS NULL))
   then 'dbo.usp_SPWithoutParam1And2'

   END

   print @sql
   EXEC sp_executesql @sql
end

答案 1 :(得分:2)

恐怕你的团队负责人错了。

引用MSDN

  

CASE表达式不能用于控制执行的流程   Transact-SQL语句,语句块,用户定义的函数和   存储过程。有关流控制方法的列表,请参见   流控制语言(Transact-SQL)。

Transact-SQL流控制语言关键字(那里没有CASE):

 - BEGIN...END
 - RETURN
 - BREAK
 - TRY...CATCH
 - CONTINUE
 - WAITFOR
 - GOTO label
 - WHILE
 - IF...ELSE

另一方面,您的查询可以得到改进(如果满足条件,则无需检查其他IF(s)

CREATE PROCEDURE dbo.usp_SPCaller
@Input_Param1 NVARCHAR(100) = NULL,
@Input_Param2 NVARCHAR(100) = NULL

AS
BEGIN
SET NOCOUNT ON    

IF ((@Input_Param1 IS NOT NULL) AND (@Input_Param2 IS NOT NULL))
   BEGIN
       EXEC dbo.usp_SPWithParam1And2
   END 
ELSE IF ((@Input_Param1 IS NOT NULL) AND (@Input_Param2 IS NULL))
   BEGIN
       EXEC dbo.usp_SPWithParam1Only
   END
ELSE IF ((@Input_Param1 IS NULL) AND (@Input_Param2 IS NOT NULL))
   BEGIN
       EXEC dbo.usp_SPWithParam2Only
   END  
ELSE IF ((@Input_Param1 IS NULL) AND (@Input_Param2 IS NULL))
   BEGIN
       EXEC dbo.usp_SPWithoutParam1And2
   END

编辑-由于动态查询CASE

话虽如此,但有一种方法可以通过动态查询来强制执行CASE行为,例如 Sushil Sharma 发布的行为。

但是有一个捕获!使用动态查询(不需要时)会通过SQL Injection为任何潜在的附加攻击者提供一个攻击向量,因此在我看来,最好使用简单的解决方案IF ... ELSE IF执行已经预定义的过程。

答案 2 :(得分:1)

告诉您的领导者他错了(也许以更礼貌的方式)。 T-SQL中没有CASE 语句,只有大小写 expression 。因此,如果您现在拥有的话,请继续使用它们。

答案 3 :(得分:1)

您的线索有误。

  

“ CASE表达式不能用于控制Transact-SQL语句,语句块,用户定义的函数和存储过程的执行流程。”

Reference