2017-04-06 44 views
1

这对于MS SQL(> 2008,但主要是版本不可知)更具体。UDF中的返回位

我正在寻找简化对SQL Server中存储过程的检查。 我想直到结束是这样的:

IF (dbo.PROC_EXISTS(N'MY_STORED_PROC_NAME') = 1) 
    DROP PROCEDURE MY_STORED_PROC_NAME 
GO 

我目前有:

SELECT 
CAST(
    CASE 
     WHEN EXISTS (
      SELECT * 
      FROM sys.objects 
      WHERE object_id = OBJECT_ID(N'GET_ALT_SCHEDULE') 
         AND type IN (N'P', N'PC') 
     ) 
     THEN 'TRUE' 
     ELSE 'FALSE' 
     END 
AS BIT 
) 

RETURNS 1 -- TRUE 
RETURNS 0 -- FALSE 

当我把这个代码的函数里面,这是行不通的,因为我不能返回一个来自select语句的值。

CREATE FUNCTION PROC_EXISTS(@SPName NVARCHAR) 
    RETURNS BIT 
AS 

BEGIN 

DECLARE @Answer BIT 

SET @Answer = SELECT -- Incorrect syntax near 'SELECT' 
    CAST(
     CASE 
      WHEN EXISTS (
       SELECT * 
       FROM sys.objects 
       WHERE object_id = OBJECT_ID(@SPName) 
          AND type IN (N'P', N'PC') 
      ) 
      THEN 1 
      ELSE 0 
      END 
    AS BIT 
    ) 
RETURN @Answer 
END 

有人可以提供一些见解发生了什么?如果你可以解决这个函数如何组成返回我正在寻找的东西(按照第一个代码块)

或者一个函数可能不适合这种情况。但请说明原因。

回答

2

刚刚使用object_id()怎么样?

if object_id(N'dbo.proc_name') is not null 
drop procedure dbo.proc_name; 

要纠正你的函数代码:

您的输入被指定为nvarchar没有大小,因此它默认为1.改变它的长度,而不是sysname

删除select,因为您已经使用set。或者,您可以删除set并使用select @Answer = cast ...

create function proc_exists (@spname sysname) 
returns bit as 
begin; 
    declare @Answer bit; 
    set @Answer = case when exists (
     select * 
     from sys.objects 
     where object_id = object_id(@spname) 
     and type in (N'P', N'PC') 
    ) 
     then 1 else 0 end; 
    return @Answer; 
end; 
go 

rextester演示:http://rextester.com/EYWVBY20177

+0

谢谢!这正是我所期待的。我可能会从现在开始使用object_id()不为空。这就是我真正想要的。在功能上也赞同矿石深入的解释。很高兴在行动中看到这一点。 – EdwinJackson

+0

@EdwinJackson乐于助人! – SqlZim