DROP ... CREATE VS ALTER(DROP…CREATE vs ALTER)

2019-09-02 07:39发布

当谈到创建存储过程,视图,函数等等,是它更好地做一个DROP ... CREATE或ALTER的对象?

我见过无数的“标准”的文件,说明做DROP ... CREATE,但我已经看到了许多意见和论据倡导的ALTER方法。

该ALTER方法保留的安全,而我听说DROP ... CREATE方法强制对整个SP进行重新编译它的执行,而不是仅仅AA语句级重新编译的第一次。

有人可以告诉我,如果还有其他的优点/缺点使用一个比其他?

Answer 1:

ALTER也将迫使整个程序重新编译。 语句级重新编译应用到报表中的程序,例如。 单个SELECT,被重新编译,因为底层表改变,W / O型的任何改变的步骤。 它甚至不会有可能选择重新编译的程序ALTER只是某些声明,以了解在SQL文本是什么改变一个ALTER程序服务器必须......编译后。

对于所有的对象ALTER始终是更好,因为它保留了所有的安全性,所有扩展属性,所有依赖的所有约束。



Answer 2:

这是我们的做法:

if object_id('YourSP') is null
    exec ('create procedure dbo.YourSP as select 1')
go
alter procedure dbo.YourSP
as
...

该代码创建,如果它不存在,就对存储过程的“存根”,否则它的ALTER。 这样的程序的任何现有的权限将被保留,即使多次执行脚本。



Answer 3:

改变一般都比较好。 如果删除和创建,你可以失去与该对象关联的权限。



Answer 4:

与SQL Server 2016 SP1开始,您现在可以使用的选项CREATE OR ALTER语法存储过程,函数,触发器和视图。 请参阅创建或更改-在SQL Server中的另一个伟大的语言增强2016 SP1上的SQL Server数据库引擎博客。 例如:

CREATE OR ALTER PROCEDURE dbo.MyProc
AS
BEGIN
    SELECT * FROM dbo.MyTable
END;


Answer 5:

如果你有一个函数/存储过程是从例如一个网站叫做非常频繁,可能会引发问题。

该存储过程将被丢弃几毫秒/秒,在此期间,所有查询都将失败。

如果你做一个ALTER,你没有这个问题。

新创建的存储过程的模板,通常是这种形式:

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = '<name>')
    BEGIN
        DROP PROCEDURE <name>
    END
GO

CREATE PROCEDURE <name>
......

然而,相反的是更好,海事组织:

如果storedproc /功能/等不存在,用伪选择语句来创建它。 然后,ALTER总能工作 - 它永远不会被丢弃。

我们有专门的存储过程,所以我们存储的特效/函数通常是这样的:

EXEC Utils.pAssureExistance 'Schema.pStoredProc'
GO

ALTER PROCECURE Schema.pStoredProc
...

我们使用功能相同的存储过程:

EXEC Utils.pAssureExistance 'Schema.fFunction'
GO

ALTER FUNCTION Schema.fFunction
...

在Utils.pAssureExistance我们做一个IF,并期待在第一个字符之后。“”如果这是一个‘F’,我们创建了一个虚拟fonction,如果它是‘P’,我们创建了一个虚拟的存储过程。

不过要小心,如果你创建一个虚拟的标量函数,和您的ALTER是一个表值函数时,ALTER FUNCTION将失败,说这是不兼容的。

同样,Utils.pAssureExistance才能得心应手,另外还有可选参数

EXEC Utils.pAssureExistance 'Schema.fFunction', 'TableValuedFunction'

将创建一个虚拟的表值函数,

Additionaly,我可能是错的,但我认为,如果你做一个下降的过程,目前的查询使用存储的过程,它会失败。

但是,ALTER程序将等待所有查询停止使用存储过程,然后改变它。 如果查询被“锁定”了太久的存储过程(比如一对夫妇秒),ALTER将停止等待锁,反正改变存储过程:使用存储过程在这一点上可能会失败查询。



Answer 6:

我不知道是否有可能做出这样的毯子评论,并说“ALTER更好”。 我想,这一切视情况而定。 如果您需要这种细粒度的权限管理下到过程级别,你应该在一个单独的程序处理这个问题。 有具有删除并重新好处。 它清除了现有的安全并重置它什么是可预见的。

我已经使用除去/重新创建总是首选。 我还发现它更容易将它们存储在源代码控制。 而不是做的....如果存在不改变,如果不存在,就创建。

随着中说......如果你知道你在做什么?我不认为这都不算什么。



Answer 7:

你问过具体涉及到不包含任何数据,并从理论上DB对象的问题不应该经常改变。

它可能是你可能需要编辑这些对象,但不是每5分钟。 正因为如此,我认为你已经击中头部锤 - 权限。

简短的回答,不是一个真正的问题,只要权限不是问题



Answer 8:

DROP通常失去权限和任何扩展属性。

在一些UDF的, ALTER也将失去扩展属性(绝对的SQL Server 2005上的多语句表值函数)。

我通常不DROPCREATE除非我也重新创建这些事情(或者知道我要失去他们)。



Answer 9:

我们以前使用改变,而我们在发展中既工作创造新的功能或修改功能。 当我们与我们的开发和测试完成后我们会再做下降和创造。 这modifys对特效的日期/时间戳记,所以你可以按照日期/时间对它们进行排序。

它也让我们看到了什么是按日期对我们发出的每个交付bundeled。



Answer 10:

添加与是否存在更好的降低,因为如果你有多个环境,当您移动脚本QA或测试或督促你不知道,如果脚本在那样的环境已经存在。 通过增加一个下降(如果它已经存在),然后添加你就不管存不存在覆盖。 然后,您需要重新申请权限,但其更好然后听你的安装脚本错误-ED了。



Answer 11:

如果执行DROP,然后使用CREATE,你有几乎使用ALTER VIEW语句相同的效果。 问题是,你需要对谁可以和不可以使用视图完全重新建立您的权限。 ALTER保留相关性信息,并设置任何权限。



Answer 12:

从一个滴可用性点,创造比ALTER更好。 阿尔特将在不包含对象数据库失败,但有一个IF EXISTS DROP然后CREATE将在数据库中工作与对象已经存在或在对象不存在的数据库。 在Oracle和PostgreSQL您通常创建函数和过程与语句CREATE或更换不相同的SQL SERVER IF EXISTS DROP然后CREATE。 如果SQL Server拾取,这个小,但非常方便的语法,这将是很好。

这是我会怎么做。 把所有这一切在一个脚本中给定对象。

IF EXISTS ( SELECT 1
            FROM information_schema.routines
            WHERE routine_schema = 'dbo'
              AND routine_name   = '<PROCNAME'
              AND routine_type   = 'PROCEDURE' )
BEGIN
    DROP PROCEDURE <PROCNAME>
END
GO


CREATE PROCEDURE <PROCNAME>
AS
BEGIN
END
GO

GRANT EXECUTE ON <PROCNAME> TO <ROLE>
GO


文章来源: DROP…CREATE vs ALTER