|
Top Previous |
alter table DOCUMENT add Z_TIMER int null GO alter table DOCUMENT add CNT_PAGES int null GO exec sp_addextendedproperty N'MS_Description', N'Кол-во страниц', N'user', N'dbo', N'table', N'DOCUMENT', N'column', N'CNT_PAGES' GO
--Внимание! после этого вручную передвиньте поля Z_TIMER и CNT_PAGES так, чтобы все Z_LINK ... были последними
EXEC sp_configure 'allow updates', 1 Reconfigure with override GO
update sysindexes set [name]='PK_DOCUMENT' where [name]='PK_Table1' GO
--Внимание! Выключается изменение системных таблиц. Если вдруг это нужно для других баз на сервере - не выполняйте следующие 3 строки
EXEC sp_configure 'allow updates', 0 Reconfigure with override GO
CREATE TABLE [dbo].[TIMER] ( [Z_TIMER] [int] IDENTITY (1, 1) NOT NULL , [Z_DOCUMENT] [int] NOT NULL , [D_TIMER] [smalldatetime] NOT NULL , [D_REAL] [smalldatetime] NOT NULL , [uId] [smallint] NOT NULL , [C_TIMER] [tinyint] NOT NULL , [N_TIMER] [varchar] (127) COLLATE Cyrillic_General_CI_AS NULL ) ON [PRIMARY] GO
ALTER TABLE [dbo].[TIMER] WITH NOCHECK ADD CONSTRAINT [PK_TIMER] PRIMARY KEY CLUSTERED ( [Z_TIMER] ) ON [PRIMARY] GO
ALTER TABLE [dbo].[TIMER] ADD CONSTRAINT [DF_TIMER_uId] DEFAULT (user_id()) FOR [uId] GO
CREATE INDEX [DOCUMENT] ON [dbo].[TIMER]([Z_DOCUMENT]) ON [PRIMARY] GO
CREATE INDEX [D_USER] ON [dbo].[TIMER]([D_TIMER], [uId]) ON [PRIMARY] GO
exec sp_addextendedproperty N'MS_Description', N'вид таймера 1-обычный 2-сообщение', N'user', N'dbo', N'table', N'TIMER', N'column', N'C_TIMER' GO
grant SELECT, UPDATE, DELETE on TIMER to public GO
ALTER PROCEDURE uGetDocument @Z_DOCUMENT_KIND tinyint=null, @N_DOCUMENT varchar(50)=null, @uId int=null, @D_BEGIN smalldatetime=null, @D_END smalldatetime=null, @C_BY_INSERTED bit=null -- null без дат, 1 по D_INSERTED, 0 по D_DOCUMENT AS select D.*, U.[name] as N_USER, T.D_REAL as D_REAL_TIMER, T.C_TIMER, T.N_TIMER from DOCUMENT D (nolock index(PK_DOCUMENT)) left join sysusers U (nolock index(ncsysusers2)) on U.uId=D.uId left join TIMER T (nolock index(PK_TIMER)) on T.Z_TIMER=D.Z_TIMER where ( isNull(@Z_DOCUMENT_KIND,0)=0 or D.Z_DOCUMENT_KIND=@Z_DOCUMENT_KIND ) and (@N_DOCUMENT is null or D.N_DOCUMENT like @N_DOCUMENT+'%') and (@uId is null or D.uId=user_id()) and ( @C_BY_INSERTED is null or (@C_BY_INSERTED=1 and D.D_INSERTED between @D_BEGIN and dateadd(dd, 1, @D_END)) or (@C_BY_INSERTED=0 and D.D_DOCUMENT between @D_BEGIN and @D_END) ) and D.Z_DOCUMENT_KIND in (--обязательная проверка прав на чтение select Z_DOCUMENT_KIND from dbo.fGetGrantTable(1) ) order by D.D_DOCUMENT GO
CREATE PROCEDURE uGetDocumentByTimer @flOnlyMy bit, @flOnlyOnTimer bit AS select D.*, U.[name] as N_USER, T.D_REAL as D_REAL_TIMER, T.C_TIMER, T.N_TIMER from DOCUMENT D (nolock index(PK_DOCUMENT)) inner join TIMER T (nolock index(PK_TIMER)) on T.Z_TIMER=D.Z_TIMER and (@flOnlyMy=0 or T.uId=user_id()) and (@flOnlyOnTimer=0 or T.D_REAL<getdate()) left join sysusers U (nolock index(ncsysusers2)) on U.uId=D.uId where (not D.Z_TIMER is null) GO grant execute on uGetDocumentByTimer to public GO
CREATE PROCEDURE uGetTimersForDoc @Z_DOCUMENT int AS select T.*, U.[name] from TIMER T (nolock index(PK_TIMER)) inner join sysusers U (nolock index(ncsysusers2)) on U.uId=T.uId where T.Z_DOCUMENT=@Z_DOCUMENT GO grant execute on uGetTimersForDoc to public GO
CREATE FUNCTION fGetTimers(@NOW smalldatetime) RETURNS @res TABLE ( C_COUNT int, D_REAL smalldatetime, C_TIMER tinyint, N_TIMER varchar(127), Z_DOCUMENT int, Z_TIMER int) AS --возвращает кол-во звонящих таймеров и текст+вид самого раннего таймера для пользователя BEGIN declare @C_COUNT int, @Z_TIMER int select @C_COUNT=count(*), @Z_TIMER=min(Z_TIMER) from TIMER (nolock index(D_USER)) where uId=user_id() and D_REAL<@NOW insert @res select @C_COUNT, D_REAL, C_TIMER, N_TIMER, Z_DOCUMENT, Z_TIMER from TIMER (nolock index(PK_TIMER)) where Z_TIMER=@Z_TIMER RETURN END GO grant select on fGetTimers to public GO
CREATE TRIGGER trTIMERUpdateDelete on TIMER for UPDATE, DELETE as --запрещает править чужие таймеры BEGIN if is_member('dbo')=1 goto l_exit if exists(select * from deleted where uId<>user_id()) begin RAISERROR ('Можно изменять только свои таймеры', 16, 1) ROLLBACK TRANSACTION end l_exit: END GO
CREATE FUNCTION fGetTimerForDoc(@Z_DOCUMENT int) RETURNS int AS --возвращает ид. самого раннего таймера для документа BEGIN declare @res int select @res = Z_TIMER from TIMER (nolock index(DOCUMENT)) where Z_DOCUMENT=@Z_DOCUMENT and D_REAL=( select min(D_REAL) from TIMER (nolock index(DOCUMENT)) where Z_DOCUMENT=@Z_DOCUMENT ) RETURN @res --may be NULL END GO grant execute on fGetTimerForDoc to public GO
CREATE TRIGGER trTIMER on TIMER for INSERT, UPDATE, DELETE as --отслеживает линк Z_TIMER в документе BEGIN create table #temp_trTIMER (Z_DOCUMENT int) insert into #temp_trTIMER select distinct Z_DOCUMENT from inserted insert into #temp_trTIMER select distinct Z_DOCUMENT from deleted where not Z_DOCUMENT in (select Z_DOCUMENT from #temp_trTIMER) update D set D.Z_TIMER=dbo.fGetTimerForDoc(D.Z_DOCUMENT) from #temp_trTIMER T inner join DOCUMENT D (index(PK_DOCUMENT)) on D.Z_DOCUMENT=T.Z_DOCUMENT END GO
ALTER TRIGGER trDOCUMENT_PAGEInsert ON DOCUMENT_PAGE FOR INSERT AS --проверяет, что можно добавлять страницы --отслеживает калькулятор кол-ва страниц в документе BEGIN set nocount on if exists(select * from inserted I inner join DOCUMENT DC on DC.Z_DOCUMENT=I.Z_DOCUMENT where dbo.fIsGrantRead(DC.Z_DOCUMENT_KIND, 5)=0 --нет прав на редактирование and ( --нет прав на сканирование dbo.fIsGrantRead(DC.Z_DOCUMENT_KIND, 4)=0 --прошло время после сканирования or dbo.fIsTimeExpired(DC.D_INSERTED,2,getdate())=1 ) ) begin raiserror('Нет прав на добавление страниц', 16, 1) ROLLBACK TRANSACTION end update D set D.CNT_PAGES=dbo.fGetCountPagesForDoc(D.Z_DOCUMENT) from inserted I inner join DOCUMENT D on D.Z_DOCUMENT=I.Z_DOCUMENT END GO
ALTER TRIGGER trDOCUMENT_PAGEDelete ON DOCUMENT_PAGE FOR DELETE AS --отслеживает калькулятор кол-ва страниц в документе BEGIN set nocount on INSERT INTO [CHANGE_ALL]([Z_OBJECT], [Z_OBJECT_DETAIL], [C_KIND], [N_FIELD], [CAPTION], [OLD_V], [NEW_V], [F_DELETE]) select Z_DOCUMENT, Z_DOCUMENT_PAGE, 2, 'DOCUMENT_PAGE', 'удаление страницы', 'стр №' + cast(C_DOCUMENT_PAGE as varchar(5)) + isNull(N_NOTE,''), --' от '+convert(varchar(30), D_DOCUMENT, 4), '', 1 from deleted update D set D.CNT_PAGES=dbo.fGetCountPagesForDoc(D.Z_DOCUMENT) from deleted DL inner join DOCUMENT D on D.Z_DOCUMENT=DL.Z_DOCUMENT END GO
ALTER TRIGGER trDOCUMENTTrace ON DOCUMENT FOR UPDATE AS BEGIN set nocount on declare @s_old VARCHAR(500) declare @s_new VARCHAR(500) declare @sUser VARCHAR(80) declare @sField VARCHAR(80) declare @sDesc varchar(80) declare @sSQL VARCHAR(250) declare @REC_ID int, @table_id int declare @cnt int declare @i int CREATE TABLE #TempValue ( AValue VARCHAR(500), ) set @cnt=(select info from sysobjects where name='DOCUMENT') set @table_id=object_id('DOCUMENT') set @sUser = USER select D.* into #TempD from deleted d select I.* into #TempI from inserted I
DECLARE cTrDocumentHistory CURSOR READ_ONLY FOR select Z_DOCUMENT from inserted OPEN cTrDocumentHistory while 1=1 begin FETCH NEXT FROM cTrDocumentHistory INTO @REC_ID if @@fetch_status<>0 begin close cTrDocumentHistory DEALLOCATE cTrDocumentHistory BREAK end
set @i=2--отсчет полей - первое - ключевое while @i<=@cnt begin set @sField = (select [name] from syscolumns where [id] = @table_id and [colid] = @i) if (not @sField is null) and (@sField<>'Z_TIMER') and (@sField<>'CNT_PAGES') and (@sField<>'D_INSERTED') and (@sField<>'uId') begin --RAISERROR ('not @sField is null', 16, 1) delete from #TempValue set @sSQL = 'INSERT INTO #TempValue (AValue) select cast('+@sField+ ' as VARCHAR(250)) from #TempD where Z_DOCUMENT='+cast(@REC_ID as varchar) exec (@sSQL) set @s_old=null select @s_old=AValue from #TempValue
delete from #TempValue set @sSQL = 'INSERT INTO #TempValue (AValue) select cast('+@sField+ ' as VARCHAR(250)) from #TempI where Z_DOCUMENT='+cast(@REC_ID as varchar) exec (@sSQL) set @s_new=null select @s_new=AValue from #TempValue
--выяснены старое и новое значения, сравнениея и вставка при необх. if isNull(@s_new,'') != isNull(@s_old,'') begin
set @sDesc = (select cast(value as VARCHAR(80)) from sysproperties where [id] = @table_id and [smallid] = @i and [name]='MS_Description') if @sDesc is null set @sDesc=@sField
INSERT INTO [CHANGE_ALL]([Z_OBJECT], [C_KIND], [N_FIELD], [CAPTION], [OLD_V], [NEW_V], [F_DELETE]) VALUES(@REC_ID, 1, isnull(@sField,''), isnull(@sDesc,''), @s_old, @s_new, 0) end end -->>(not @sField is null) set @i = @i + 1 end -->>while @i<=@cnt end -->>while 1=1
END GO
update DOCUMENT set CNT_PAGES = dbo.fGetCountPagesForDoc(Z_DOCUMENT) GO
|