Синтаксис CREATE / ALTER для хранимых процедур SQL Server в сценарии репликации? - PullRequest
2 голосов
/ 14 февраля 2011

Я храню все свои операторы DDL T-SQL в проекте базы данных Visual Studio под управлением версией. Сценарии должны всегда выполняться без ошибок, поэтому они включают синтаксис удаления / создания, например:

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

Проблема в том, что мы перешли к сценарию репликации, поэтому я больше не могу использовать мой синтаксис удаления / создания, поскольку вы не можете удалить объекты, отмеченные для репликации. Теперь мне нужно создать процедуру, если она не существует, или изменить ее, если она существует. И я не могу изменить свою IF логику, потому что я не могу создать процесс в операторе IF - я могу только удалить его. Есть идеи?


EDIT: Благодаря ответу Адама, вот что я в итоге использовал. Не знаю, почему я не подумал о выполнении строки SQL ... надо пить больше кофе.

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

Ответы [ 4 ]

5 голосов
/ 14 февраля 2011

Что вы можете сделать, это сделать, чтобы первая часть вашего скрипта создала заглушку для процедуры, если она не существует, а затем превратила остальную часть скрипта в скрипт ALTER вместо CREATE.

Например:

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

Обратите внимание, что здесь вам придется использовать sp_ExecuteSql (или что-то эквивалентное), поскольку create procedure должен быть первым оператором в пакете.

1 голос
/ 14 февраля 2011

Примером ответа Адама будет что-то вроде:

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 */
1 голос
/ 14 февраля 2011

Оберните создание хранимой процедуры в EXEC, и вы можете изменить свою логику if:

exec (N'create procedure...
0 голосов
/ 13 сентября 2011

Добавление примеров для табличных функций:

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

и скалярные функции:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...