【发布时间】:2010-10-30 14:08:59
【问题描述】:
我必须编写一个部署脚本,它可以在存储过程存在或不存在时工作。即如果它存在,那么我需要更改它,否则创建它。
如何在 sql 中做到这一点。
我使用的是 SQL Server 2005
【问题讨论】:
标签: sql sql-server-2005 stored-procedures
我必须编写一个部署脚本,它可以在存储过程存在或不存在时工作。即如果它存在,那么我需要更改它,否则创建它。
如何在 sql 中做到这一点。
我使用的是 SQL Server 2005
【问题讨论】:
标签: sql sql-server-2005 stored-procedures
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xxx]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
CREATE PROCEDURE dbo.xxx
xxx 是过程名称
【讨论】:
更好的选择可能是使用 Red-Gate SQL Compare 或 SQL Examiner 等工具来自动比较差异并生成迁移脚本。
【讨论】:
IF OBJECT_ID('SPNAME') IS NULL
-- Does Not Exists
ELSE
-- Exists
【讨论】:
最干净的方法是测试它是否存在,如果存在则删除它,然后重新创建它。您不能在 IF 语句中嵌入“create proc”语句。这应该做得很好:
IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO
CREATE PROC MySproc
AS
BEGIN
...
END
【讨论】:
如果您只处理存储过程,最简单的做法是删除 proc,然后重新创建它。您可以使用 SQL Server 中的“生成脚本”向导生成所有代码来执行此操作。
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourSproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[YourSproc]
CREATE PROCEDURE YourSproc...
【讨论】:
如果您 DROP 和 CREATE 过程,您将失去安全设置。这可能会惹恼您的 DBA 或完全破坏您的应用程序。
我要做的是创建一个微不足道的存储过程,如果它还不存在的话。之后,您可以根据自己的喜好更改存储过程。
IF object_id('YourSp') IS NULL
EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...
这样,安全设置、cmets 和其他元数据将在部署后继续存在。
【讨论】:
if object_id('YourSp') is null BEGIN ... END 中添加代码以在创建存储过程后添加适当的权限。
除了已经说过的内容之外,我还想添加一种不同的方法,并提倡使用差异化脚本部署策略。 Instead of making a stateful script that always checks the current state and acts based on that state, deploy via a series of stateless scripts that upgrade from well known versions。我已经使用了这个策略,并且它带来了巨大的回报,因为我的部署脚本现在都是“IF”免费的。
【讨论】:
我有一个允许客户扩展验证的存储过程,如果它存在我不想更改它,如果它不想创建它,我发现的最好方法:
IF OBJECT_ID('ValidateRequestPost') IS NULL
BEGIN
EXEC ('CREATE PROCEDURE ValidateRequestPost
@RequestNo VARCHAR(30),
@ErrorStates VARCHAR(255) OUTPUT
AS
BEGIN
SELECT @ErrorStates = @ErrorStates
END')
END
【讨论】:
从SQL Server 2016 CTP3 开始,您可以使用新的DIE 语句代替大的IF 包装器
语法:
删除 { 过程 |过程 } [ 如果存在 ] { [ schema_name. ] 程序 } [ ,...n ]
查询:
DROP PROCEDURE IF EXISTS usp_name
更多信息here
【讨论】:
下面的代码将检查存储过程是否已经存在。
如果存在它会改变,如果它不存在它会为你创建一个新的存储过程:
//syntax for Create and Alter Proc
DECLARE @Create NVARCHAR(200) = 'Create PROCEDURE sp_cp_test';
DECLARE @Alter NVARCHAR(200) ='Alter PROCEDURE sp_cp_test';
//Actual Procedure
DECLARE @Proc NVARCHAR(200)= ' AS BEGIN select ''sh'' END';
//Checking For Sp
IF EXISTS (SELECT *
FROM sysobjects
WHERE id = Object_id('[dbo].[sp_cp_test]')
AND Objectproperty(id, 'IsProcedure') = 1
AND xtype = 'p'
AND NAME = 'sp_cp_test')
BEGIN
SET @Proc=@Alter + @Proc
EXEC (@proc)
END
ELSE
BEGIN
SET @Proc=@Create + @Proc
EXEC (@proc)
END
go
【讨论】:
您可以编写如下查询:
IF OBJECT_ID('ProcedureName','P') IS NOT NULL
DROP PROC ProcedureName
GO
CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....
更具体地说明上述语法:
OBJECT_ID 是数据库中对象的唯一 ID 号,由 SQL Server 内部使用。由于我们传递 ProcedureName 后跟对象类型 P,它告诉 SQL Server 你应该找到名为 ProcedureName 的对象,它的类型是 程序,即P
此查询将找到该过程,如果它可用,它将删除它并创建一个新的。
有关 OBJECT_ID 和对象类型的详细信息,请访问:SYS.Objects
【讨论】: