21

Oracle 执行“创建或替换”语句。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

这就是我想要的。如果该过程不存在,请创建它,然后更改正确的代码。如果该过程确实存在,则创建失败并且alter 使用新代码更新代码。

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

有没有人有办法抑制红色文字?我尝试过的一切都会以某种方式导致“CREATE/ALTER PROCEDURE 必须是查询批处理中的第一条语句”错误。

4

3 回答 3

51

这将起作用并保持权限不变:

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
于 2012-12-13T18:37:20.420 回答
10

像这样:

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 文本的缩进级别。
于 2012-12-13T18:35:59.753 回答
6

终于有一天,SQL Server 实现了创建或替换的等效项。它们的等价物是“创建或更改”。从 SQL Server 2016 SP1 开始提供。示例用法:

use [myDatabase]
go

Create or Alter procedure myProcedure as
begin
  -- procedure code here
end
go
于 2017-02-22T18:59:20.863 回答