2012-12-13 148 views
19

Oracle会“创建或替换”语句。 Sql服务器似乎没有 - 如果你正在从企业管理器脚本化,它反而建议“放弃并创建”。在存储过程中完成授权的任何情况下,删除和创建都是不可取的,因为它会抛出数据库管理团队完成的任何授权。您确实需要“创建或替换”来帮助开发人员和管理员之间的分离。如果在sql server中不存在,则创建存储过程

我最近一直在做这样的:

use [myDatabase] 
go 

create procedure myProcedure as 
begin 
    print 'placeholder' 
end 
go 

alter procedure myProcedure as 
begin 
    -- real sproc code here 
end 
go 

此我想要做什么。如果该过程不存在,则创建它,然后更改正确的代码。如果该过程确实存在,则创建失败,并且该更新将使用新代码更新代码。

它为管理员创建了一个不同的问题,因为如果存储过程已经存在,create会引发误导性错误。当然,误导,事实上,当期望的结果发生时,你不应该看到红色错误文本。

有没有人有办法压制红色文字?我试过的所有东西都会导致'CREATE/ALTER PROCEDURE必须是查询批处理中的第一条语句'。

+0

的可能的复制[?你怎么在SQL Server中创建或更改做(http://stackoverflow.com/questions/1434160/what-do-you-do-in-sql -server-to-create-or-alter) – ruffin

+0

我要指出的是,如果您将权限作为proc的一部分编写,那么在Drop和Create中没有问题。如果您对proc有特殊权限,那么它应该是存储在源代码库中的脚本的一部分。然后当你去做改变时,那里已经有了许可。 – HLGEM

回答

46

这将工作,并保持完好的权限:

use [myDatabase] 
go 
if object_id('dbo.myProcedure', 'p') is null 
    exec ('create procedure myProcedure as select 1') 
go 
alter procedure myProcedure as 
SET NOCOUNT ON 
    -- real sproc code here. you don't really need BEGIN-END 
go 
+0

哈。我忘记了这个诀窍。 – RBarryYoung

+0

我喜欢我的开始 - 结束。 – quillbreaker

+0

这也适用于用户定义函数,这是我发现需要“改变”的地方,因为这个函数被几件事情使用。对于OP,这将是首选,恕我直言。 – granadaCoder

9

像这样:

IF NOT EXISTS (SELECT * FROM sys.objects 
       WHERE object_id = OBJECT_ID(N'[dbo].[myProcedure]') 
        AND type in (N'P', N'PC')) 
BEGIN 
    EXEC(' 
     create procedure myProcedure as 
     begin 
      print ''placeholder'' 
     end 
     ') 
END 

EXEC(' 
    alter procedure myProcedure as 
    begin 
     -- real sproc code here 
    end 
    ') 

注:

  1. 记得在动态SQL字符串您的报价翻倍。
  2. 为了便于阅读,我已经缩进了它,但这也会将额外的缩进空格添加到实际的过程列表中。如果你不明白,那么就减少动态SQL文本的缩进级别。
+0

仅供参考,我会尽量在线上发布时添加BEGIN..ENDs。只是因为我看到一个新手多次尝试向其他人的SQL添加一行,但忘记添加BEGIN.END。 – RBarryYoung

+0

外来的,真的。新行上的“GO”完全覆盖了它的范围。怎么说有人不会'开始...结束'并在'结束'之后但在'开始'之前放置更多的陈述?但这只是一个意见,每个人都有权获得一个! – RichardTheKiwi

+0

@RichardTheKiwi:这是一个罕见的错误。 (好吧,误解GO是一个常见的错误,但它通常以不同的方式表现出来,因为变量超出了范围)通常,我看到的没有BEGIN..END的问题是他们会忘记它们对于分支中的多个语句是必需的/块。当BEGIN ..END在那里,它似乎在视觉上“提醒”他们,所以他们不会把新的线路放在块之外。 (至少我从没见过那个错误) – RBarryYoung

4

终于有一天在这其中SQL Server已实施了相当于创建或替换。他们的等价物是“创建或改变”。这从SQL Server 2016 SP1起可用。用法示例:

use [myDatabase] 
go 

Create or Alter procedure myProcedure as 
begin 
    -- procedure code here 
end 
go 
相关问题