Хранимые процедуры и версионность

Jun 02, 2011 19:21

 
Решил поделится одним из вариантов по обеспечению версионного хранения исходного кода хранимых процедур для SQL Server 2005/2008

Если вы закладываете в программную архитектуру довольно солидный слой хранимых процедур, изложенный здесь материал может оказаться довольно полезным.

В этом посте описан один из подходов по обеспечению версионного хранения исходного кода хранимых процедур для SQL Server 2005/2008

Плюсы:

-Если нет Source Control Server - это единственный вариант

-Не нужно никаких дополнительных действий a la "Check in"

-Сведения можно получить прямо в ядре БД

Минусы:

-Накапливается большое количество изменений

-Для сравнения нужны сторонние утилиты

Этапы:

1. Создание таблицы, в которую будут заносится все изменения.

2. Занесение исходного кода всех хранимых процедур, функций и триггеров.

3. Создание DDL-триггера

Итак код:

--Создание таблицы для ведения всех изменений

if exists   
(    
        select *    
        from sys.tables t        
        where t.name like 'XStore_Procedure'    
)    
        drop table XStore_Procedure    
go

create table XStore_Procedure    
(    
        Id int identity (1,1 ) not null primary key,    
        Who varchar(64) not null default system_user,--пользователь из текущего сеанса    
        What int not null,--1 - insert, 2 - update, 3 - delete    
        DateWhen datetime default getdate(),    
        ProcName varchar(50) not null,--название программного блока    
        ProcSchema varchar(30) not null,--схема    
        ProcType varchar(50) not null,--тип    
        ProcCode varchar(max) null--код    
)

go

-- заполнение данными о текущем состоянии    
insert into XStore_Procedure(What,ProcName, ProcSchema,ProcType,ProcCode)    
select    
        1 as What,    
        o.name as ProcName,    
        s.name,    
        case        
                when o.type='FN' then 'FUNCTION'    
                when o.type='IF' then 'FUNCTION'    
                when o.type='TF' then 'FUNCTION'    
                when o.type='P' then 'PROCEDURE'    
                when o.type='TR' then 'TRIGGER'    
                else    
                        'NOT DEFINED'        
        end ProcType,    
        m.definition as ProcCode--объявление программного объекта    
from        
--идем по системным вьюшкам   
        sys.objects o --корневая    
                inner join        
                        sys.sql_modules m    
                                on o.object_id=m.object_id    
                                        inner join sys.schemas s    
                                                on        o.schema_id=s.schema_id    
go

--Создание триггера    
if        exists(    
select *        
from sys.triggers        
where parent_class_desc = 'DATABASE' and name = 'ChangeStoredProc')

drop trigger ChangeStoredProc on database

go

--DDL позволяет перехватывать большую часть всех событий, связанных с изменениями в схеме данных    
create trigger ChangeStoredProc on database            
for        
create_procedure, alter_procedure, drop_procedure,        
create_function, alter_function, drop_function,    
create_trigger, alter_trigger, drop_trigger    
as    
begin    
set nocount on    
--аргумент события, приходит в виде xml, из котого можно вытащить все значиния через XPath    
declare @Event xml    
set @Event=(select EventData())    
declare @EventType varchar(30)

if @Event.exist('/EVENT_INSTANCE/EventType')=1    
                set @EventType=@Event.value('data(/EVENT_INSTANCE/EventType)[1]', 'varchar(30)')

declare @op int    
set @op=0    
if @EventType like '%create%' set @op=1    
if @EventType like '%alter%' set @op=2    
if @EventType like '%drop%' set @op=3    
declare @LoginName varchar(50)    
if @Event.exist('/EVENT_INSTANCE/LoginName')=1    
                set @LoginName=@Event.value('data(/EVENT_INSTANCE/LoginName)[1]','varchar(50)')

declare @ProcName varchar(50)                    
if @Event.exist('/EVENT_INSTANCE/ObjectName')=1    
                set @ProcName=@Event.value('data(/EVENT_INSTANCE/ObjectName)[1]','varchar(50)')

declare @ProcSchema varchar(50)                    
if @Event.exist('/EVENT_INSTANCE/SchemaName')=1    
                set @ProcSchema=@Event.value('data(/EVENT_INSTANCE/SchemaName)[1]','varchar(50)')    
declare @ProcType varchar(50)                    
if @Event.exist('/EVENT_INSTANCE/ObjectType')=1    
                set @ProcType=@Event.value('data(/EVENT_INSTANCE/ObjectType)[1]','varchar(50)')    
declare @ProcCode varchar(max)    
if @Event.exist('/EVENT_INSTANCE/TSQLCommand')=1    
                set @ProcCode=@Event.value('data(/EVENT_INSTANCE/TSQLCommand)[1]','varchar(max)')    
insert into XStore_Procedure (Who, What, DateWhen, ProcName, ProcSchema, ProcType, ProcCode)    
                values(@LoginName, @op,getdate(),@ProcName,@ProcSchema, @ProcType,@ProcCode)    
end    
go    
--Ну и после можно протестировать полученный механизм    
--create procedure Test        
--as        
--begin    
--        print 'Test'        
--end    
--go    
--drop procedure Test    
--go    
--create table Test (Id int, value varchar(max))    
--go    
--create trigger TestTrig on Test    
--after insert, update, delete    
--as    
--begin    
--        print 'Test trigger!'    
--end    
--go

--drop table Test    
--go    
--create function Test (@a int)    
--returns int    
--as    
--begin    
--        return @a    
--end   
--go   
--drop function Test   
--go   
--select * from        XStore_Procedure   
--go

хранимые процедуры, source control, sql server

Previous post
Up