你在SQL Server中做什么来创建或改变?

har*_*rpo 61 sql t-sql sql-server

这一年是2009年,SQL Server没有CREATE或ALTER/REPLACE.这就是我所做的.

IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES 
           WHERE ROUTINE_NAME = 'SynchronizeRemoteCatalog' 
             AND ROUTINE_SCHEMA = 'dbo' 
             AND ROUTINE_TYPE = 'PROCEDURE')
 EXEC ('DROP PROCEDURE dbo.SynchronizeRemoteCatalog')

CREATE PROCEDURE dbo.SynchronizeRemoteCatalog
AS BEGIN
    -- body
END
Run Code Online (Sandbox Code Playgroud)

对于触发器,您必须依赖于专有系统视图.

在此期间,这是最受欢迎的惯例吗?

编辑:正如n8wrl建议的那样,官方消息表明此功能不是高优先级.因此问题.

Neo*_*isk 94

本文对在SQL Server中删除对象时丢失权限提出了一个很好的观点.

所以这是保留权限的方法:

IF OBJECT_ID('spCallSomething') IS NULL
    EXEC('CREATE PROCEDURE spCallSomething AS SET NOCOUNT ON;')
GO

ALTER PROCEDURE spCallSomething ... 
--instead of DROP/CREATE
Run Code Online (Sandbox Code Playgroud)

也适用于功能,只需更换PROCEDUREFUNCTION在上面的代码.

考虑这样做的另一个原因是容忍失败.假设您的DROP成功,但您的CREATE失败 - 您以一个损坏的数据库结束.使用ALTER方法,您将得到该对象的旧版本.


Mar*_*ith 37

这一年是2009年,SQL Server没有CREATE或ALTER/REPLACE.

这一年是2016年,它现在确实在SQL Server 2016 RTM和(2016 SP1中引入)中有DIE(Drop If ExistsCREATE OR ALTER).

Drop If Exists首先考虑需要使用此方法重新应用权限的警告仍然适用.示例语法是

DROP PROCEDURE IF EXISTS dbo.SynchronizeRemoteCatalog

GO

CREATE PROCEDURE dbo.SynchronizeRemoteCatalog
AS
  BEGIN
      BODY:
  END 

GO

/*TODO: Reapply permissions*/
Run Code Online (Sandbox Code Playgroud)

CREATE OR ALTER保留权限.示例语法是

 CREATE OR ALTER PROCEDURE dbo.SynchronizeRemoteCatalog
 AS
 BEGIN
   BODY:
 END
Run Code Online (Sandbox Code Playgroud)

相应的MSSQL虎团队博客文章解释

CREATE OR ALTER可用于可编程对象,例如:

  • 存储过程(包括本机编译)
  • 功能(Transact-SQL,包括本机编译)
  • TRIGGERS
  • VIEWS

但不能用于:

  • 需要存储的对象(表,索引和索引视图)
  • CLR用户定义的函数
  • 弃用的可编程对象(RULE和DEFAULT)
  • 非可编程对象(例如CREATE ASSEMBLY,CREATE TABLE或CREATE - SCHEMA).在这些对象上,CREATE和ALTER的语法与语法和可用性角度非常不同.


Rem*_*anu 7

每次开发人员写IF EXISTS(...) DROP密封时,小狗都会被殴打.根据应用程序模式的当前版本:版本控制和数据库,您应该确切地知道数据库中的内容和升级脚本应该使CREATe或ALTER适当.

  • 我发现这是允许我的部署脚本安全运行多次的合理方法.此外,如果我可以在不感冒的情况下打上封印...... (13认同)
  • 为什么?最好是安全而不是抱歉!你有没有一个脚本失败的你突然间你要丢弃的一个sproc仍然在数据库中挥之不去?我总是首先进行IF EXISTS()检查 - 只是为了安全起见!你有没有一个愚蠢的临时DBA运行你的一些脚本几次而不是一次? (8认同)
  • 我想我不是生活在理想的世界里.如果脚本在客户端的计算机上引发错误,即使在版本控制和测试之后,我该怎么说?"太糟糕了.它应该有效,所以我无能为力." 雷木思,我会破产. (3认同)
  • @marc:是的,愚蠢的dbas ......我只是试图在这里播种,让ppl更多地考虑数据库作为版本控制下的资源,而不是'让我们打开ssms并修改表!'.我知道在实践中不可能不依赖于exists()(或者objec_id不是null,我实际上更喜欢它,比如gbn).我猜海豹幼崽注定了...北极恶臭虫 (3认同)

Dan*_*Dan 6

我们遇到了需要更新远程站点的情况,但我们没有DROP权限.到目前为止,我们一直在使用SSMS 2008 R2中内置的"DROP和CREATE"脚本,但现在我们需要更改.我们创建了三个模板,当我们需要更新存储过程或函数时,我们将其放在相应的ALTER脚本之上:

—- Stored Procedure
IF OBJECT_ID('[dbo].[<Name_Of_Routine, , >]') IS NULL
EXEC('CREATE PROCEDURE [dbo].[<Name_Of_Routine, , >] AS SET NOCOUNT ON;')
EXEC('GRANT EXECUTE ON [<Name_Of_Routine, , >] TO Public AS dbo;')
GO

—- Scalar Function
IF OBJECT_ID('[dbo].[<Name_Of_Routine, , >]') IS NULL
EXEC('CREATE FUNCTION [dbo].[<Name_Of_Routine, , >] (@i INT) RETURNS INT AS BEGIN RETURN 0 END;')
EXEC('GRANT EXECUTE ON [<Name_Of_Routine, , >] TO Public AS dbo;')
GO

—- Table-based Function
IF OBJECT_ID('[dbo].[<Name_Of_Routine, , >]') IS NULL
EXEC('CREATE FUNCTION [dbo].[<Name_Of_Routine, , >] (@i INT) RETURNS @O TABLE(i INT) AS BEGIN INSERT INTO @O SELECT 0 RETURN END;')
GO
Run Code Online (Sandbox Code Playgroud)

在每次CREATE之后,任何特殊权限都会被编写脚本(无法为表函数分配权限).之后,ALTER不会更改它,如果他们添加或修改权限,它们将保留.这样做,复制函数或存储过程的名称是一项简单的任务,并使用模板参数替换来自动完成这些scriptlet.

现在,我希望微软的优秀人员能够将其添加到他们的"Script ___ as"列表中,或者让我们能够创建自己的脚本,以便这个脚本来自"烘焙"

您可能需要在SQL Server反馈条目后面加以重视:https: //connect.microsoft.com/SQLServer/feedback/details/344991/create-or-alter-statement.这似乎是仍然可以访问公开的几个之一,他们指出,他们"已经开始为此进行可行性审查,以决定是否能在不久的将来出货这一点." 声音越多,就越有可能发生这种情况!

(更新:现在还使用以下触发器和视图代码)

-- Triggers
IF OBJECT_ID('[dbo].[<Name_Of_Trigger, , >]') IS NULL -- Check if Trigger Exists
    EXEC('CREATE TRIGGER [dbo].[<Name_Of_Trigger, , >] ON [<Name_Of_Table, , >] AFTER UPDATE AS SET NOCOUNT ON;') -- Create dummy/empty SP
GO

-- Views
IF OBJECT_ID('[dbo].[<Name_Of_View, , >]') IS NULL -- Check if View Exists
    EXEC('CREATE VIEW [dbo].[<Name_Of_View, , >] AS SELECT 1;') -- Create dummy/empty View
GO
Run Code Online (Sandbox Code Playgroud)


n8w*_*wrl 1

看起来已经有一段时间了:链接文本

对我来说典型的脚本:

IF EXISTS (SELECT name FROM sysobjects WHERE name = 'ig_InsertDealer' AND type = 'P')
    DROP PROC dbo.ig_InsertDealer
GO 
CREATE PROCEDURE dbo.ig_InsertDealer
...
GO
GRANT EXECUTE ON dbo.ig_InsertDealer TO ...
GO
Run Code Online (Sandbox Code Playgroud)

  • 我建议使用a)“sys”模式,b)更集中的系统视图,例如表的sys.tables,触发器的sys.triggers等,而不仅仅是通用的“sysobjects”(很快就会被弃用) )。 (3认同)