如果不存在,则通过代码创建新函数

meh*_*tfi 16 sql-server t-sql sql-server-2008-r2 functions

我想在我的数据库中通过脚本创建新函数。脚本代码如下:

IF Exists(Select * From sys.sysobjects A Where A.name =N'fn_myfunc' and xtype=N'FN') return;

CREATE FUNCTION fn_myfunc ()
returns varchar(10)
AS Begin
...
End
Run Code Online (Sandbox Code Playgroud)

但是当我执行上面的脚本时,SQL Server 返回一个错误:

'CREATE FUNCTION' must be the first statement in a query batch.
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 18

2017 年 1 月更新 - SQL Server 2016+ / Azure SQL 数据库

SQL Server 2016 和当前版本的 Azure SQL 数据库现在对函数、过程、表、数据库等具有以下语法。 ( DROP IF EXISTS):

DROP FUNCTION IF EXISTS dbo.fn_myfunc;
Run Code Online (Sandbox Code Playgroud)

SQL Server 2016 Service Pack 1 为模块(函数、过程、触发器、视图)添加了更好的功能,这意味着不会丢失权限或依赖项 ( CREATE OR ALTER):

CREATE OR ALTER FUNCTION dbo.fn_myfunc ...
Run Code Online (Sandbox Code Playgroud)

这两种语法增强都可以导致用于源代码控制、部署等的脚本更加简单。

但是,如果您正在使用...


旧版本

当您从 Management Studio 编写脚本时,您需要执行 SQL Server 执行的操作:

IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE type = 'FN' AND name = 'fn_myfunc')
BEGIN
    DECLARE @sql NVARCHAR(MAX);
    SET @sql = N'CREATE FUNCTION ...';
    EXEC sp_executesql @sql;
END
Run Code Online (Sandbox Code Playgroud)

或者你可以说:

BEGIN TRY
    DROP FUNCTION dbo.fn_myfunc;
END TRY
BEGIN CATCH
    PRINT 'Function did not exist.';
END CATCH
GO
CREATE FUNCTION...
Run Code Online (Sandbox Code Playgroud)

或者你可以说:

DROP FUNCTION dbo.fn_myfunc;
GO
CREATE FUNCTION...
Run Code Online (Sandbox Code Playgroud)

(如果函数不存在,您将在此处收到错误消息,但脚本将从下一个 GO 开始继续执行,因此无论 drop 是否有效,该函数仍将(重新)创建。)

请注意,如果您删除该函数并重新创建它,您将失去权限和潜在的依赖信息。