Title4

 

 

Обновление до версии 3.3

Top  Previous 

 

· до версии 3.3

 

 

 

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