当谈到创建存储过程,视图,函数等等,是它更好地做一个DROP ... CREATE或ALTER的对象?
我见过无数的“标准”的文件,说明做DROP ... CREATE,但我已经看到了许多意见和论据倡导的ALTER方法。
该ALTER方法保留的安全,而我听说DROP ... CREATE方法强制对整个SP进行重新编译它的执行,而不是仅仅AA语句级重新编译的第一次。
有人可以告诉我,如果还有其他的优点/缺点使用一个比其他?
当谈到创建存储过程,视图,函数等等,是它更好地做一个DROP ... CREATE或ALTER的对象?
我见过无数的“标准”的文件,说明做DROP ... CREATE,但我已经看到了许多意见和论据倡导的ALTER方法。
该ALTER方法保留的安全,而我听说DROP ... CREATE方法强制对整个SP进行重新编译它的执行,而不是仅仅AA语句级重新编译的第一次。
有人可以告诉我,如果还有其他的优点/缺点使用一个比其他?
ALTER也将迫使整个程序重新编译。 语句级重新编译应用到报表中的程序,例如。 单个SELECT,被重新编译,因为底层表改变,W / O型的任何改变的步骤。 它甚至不会有可能选择重新编译的程序ALTER只是某些声明,以了解在SQL文本是什么改变了一个ALTER程序服务器必须......编译后。
对于所有的对象ALTER始终是更好,因为它保留了所有的安全性,所有扩展属性,所有依赖的所有约束。
这是我们的做法:
if object_id('YourSP') is null
exec ('create procedure dbo.YourSP as select 1')
go
alter procedure dbo.YourSP
as
...
该代码创建,如果它不存在,就对存储过程的“存根”,否则它的ALTER。 这样的程序的任何现有的权限将被保留,即使多次执行脚本。
改变一般都比较好。 如果删除和创建,你可以失去与该对象关联的权限。
与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;
如果你有一个函数/存储过程是从例如一个网站叫做非常频繁,可能会引发问题。
该存储过程将被丢弃几毫秒/秒,在此期间,所有查询都将失败。
如果你做一个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将停止等待锁,反正改变存储过程:使用存储过程在这一点上可能会失败查询。
我不知道是否有可能做出这样的毯子评论,并说“ALTER更好”。 我想,这一切视情况而定。 如果您需要这种细粒度的权限管理下到过程级别,你应该在一个单独的程序处理这个问题。 有具有删除并重新好处。 它清除了现有的安全并重置它什么是可预见的。
我已经使用除去/重新创建总是首选。 我还发现它更容易将它们存储在源代码控制。 而不是做的....如果存在不改变,如果不存在,就创建。
随着中说......如果你知道你在做什么?我不认为这都不算什么。
你问过具体涉及到不包含任何数据,并从理论上DB对象的问题不应该经常改变。
它可能是你可能需要编辑这些对象,但不是每5分钟。 正因为如此,我认为你已经击中头部锤 - 权限。
简短的回答,不是一个真正的问题,只要权限不是问题
DROP
通常失去权限和任何扩展属性。
在一些UDF的, ALTER
也将失去扩展属性(绝对的SQL Server 2005上的多语句表值函数)。
我通常不DROP
和CREATE
除非我也重新创建这些事情(或者知道我要失去他们)。
我们以前使用改变,而我们在发展中既工作创造新的功能或修改功能。 当我们与我们的开发和测试完成后我们会再做下降和创造。 这modifys对特效的日期/时间戳记,所以你可以按照日期/时间对它们进行排序。
它也让我们看到了什么是按日期对我们发出的每个交付bundeled。
添加与是否存在更好的降低,因为如果你有多个环境,当您移动脚本QA或测试或督促你不知道,如果脚本在那样的环境已经存在。 通过增加一个下降(如果它已经存在),然后添加你就不管存不存在覆盖。 然后,您需要重新申请权限,但其更好然后听你的安装脚本错误-ED了。
如果执行DROP,然后使用CREATE,你有几乎使用ALTER VIEW语句相同的效果。 问题是,你需要对谁可以和不可以使用视图完全重新建立您的权限。 ALTER保留相关性信息,并设置任何权限。
从一个滴可用性点,创造比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