开发者

CREATE/ALTER syntax for SQL Server stored procs in replication scenario?

I store all of my T-SQL DDL statements in a Visual Studio database project under version control. The scripts are meant to always run without error, so they include a drop/create syntax like so:

use MyDatabase
go
if objectproperty(object_id('dbo.MyProcName'), 'IsProcedure') = 1 begin
    drop procedure dbo.MyProcName as
end
go
-----------------------------------------------------------------------
-- $Id: $
-- Notes: blah blah
-----------------------------------------------------------------------
create procedure dbo.MyProcName as
--...
go

Trouble is, we've moved to a replication scenario so I can no longer use my drop/create syntax because you cannot drop objects marked for replication. Now I need to create the proc if it doesn't exist, or alter it if it does. And I can't reverse my IF 开发者_开发百科logic because I can't create a proc within an IF statement - I can only drop it. Any ideas?


EDIT: Thanks to Adam's answer, here's what I wound up using. Don't know why I didn't consider executing a SQL string... must drink more coffee.

use MyDatabase
go
if objectproperty(object_id('dbo.MyProcName'), 'IsProcedure') is null begin
    exec('create proc dbo.MyProcName as')
end
go
-----------------------------------------------------------------------
-- $Id: $
-- Notes: blah blah
-----------------------------------------------------------------------
alter procedure dbo.MyProcName as
    --...
go


What you can do is have the first portion of your script create a stub for the procedure if it doesn't exist, then turn the rest of the script into an ALTER script instead of a CREATE.

For example:

if objectproperty(object_id('dbo.MyProcName'), 'IsProcedure') <> 1 begin
    exec sp_ExecuteSql N'create Procedure dbo.MyProcName as select 1'
end
go
-----------------------------------------------------------------------
-- $Id: $
-- Notes: blah blah
-----------------------------------------------------------------------
alter procedure dbo.MyProcName as
--...
go

Note that you'll have to use sp_ExecuteSql (or something equivalent) here, since create procedure must be the first statement in a batch.


Wrap the creation of the stored procedure into an EXEC and you can reverse your if logic:

exec (N'create procedure...


An example like Adam's answer would be something like:

declare @ID int
select @ID = ID from sysobjects where OBJECT_NAME(ID)='Proc1' and USER_NAME(uid) = 'dbo'
if @ID is null
begin
    exec('create procedure dbo.Proc1 as')
end
else
begin
    if OBJECTPROPERTY(@ID,N'IsProcedure')=0 or OBJECTPROPERTY(@ID,N'IsMSShipped')=1
    begin
        RAISERROR('An object called dbo.Proc1 exists in the database, but is of the wrong type',16,1) WITH NOWAIT
    end
end
go
ALTER procedure [dbo].[Proc1]
     /* Body of procedure */


Adding Examples for TABLE FUNCTIONS:

IF objectproperty(object_id('dbo.udf_MyFunction'), 'IsTableFunction') is null
    EXEC sp_ExecuteSql N'CREATE FUNCTION dbo.udf_MyFunction () RETURNS @X TABLE (Id int) AS BEGIN RETURN END'
GO

and SCALAR FUNCTIONS:

IF objectproperty(object_id('dbo.udf_MyFunction'), 'IsScalarFunction') is null
    EXEC sp_ExecuteSql N'CREATE FUNCTION dbo.udf_MyFunction () RETURNS int AS BEGIN RETURN 0 END'
GO
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜