Как изменять значение поля по БП, не давая доступ на изменение записи
Подскажите кто как решает задачу, когда по БП под пользователем (например, после отработки задачи), который не имеет прав на изменение записи документа, нужно изменить состояние документа?
Тут или каждый раз создавать хранимую процедуру, специфически для изменения поля в записи, но тогда функционал обработки событий датасета не будет отрабатывать. Или давать доступ на изменение на запись, что тоже имеет свои минусы, поскольку пользователь получает полный доступ к изменению записи вручную.
Нравится
можно сделать грязный хак - изменение делать через customsql и таблице в бд дать права доступа - на видимости в системе это не отобразится и, имхо, пользователь не проведай и сим разрешением воспользоваться не сможет
Здравствуйте, Андрей!
А если попробовать таким образом, в одном элементе процесса последовательно выполнять 3 действия:
1. вызывать хранимую процедуру, которая раздаст права текущему пользователю на изменение данного документа;
2. вызывать событие изменения поля состояния документа и сохранять его;
3. вызывать хранимую процедуру, которая забирает у пользователя право на изменение этого документа.
Причем, можно раздавать право на изменение только одного поля. Так пользователь и злоупотребить этим не сможет и функционал обработки событий датасета должен отработать корректно.
Инна Безверхняя,
II линия службы поддержки Terrasoft
Спасибо Алексей и Инна за ответ.
Инна, мне ваш совет кажется наиболее подходящим, действительно - можно доработать элемент БП чтения/записи данных так, как вы написали.
Вот такую хранимую процедуру я написал, которая является универсальной для дачи или забирания права на какое-то одно действие с записью (право на чтение, изменение, удаление или изменение доступа к записи).
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go -- Процедура выполняет проставление указанного доступа на запись пользователю create procedure [dbo].[tsp_SetRightsToRecordForUser] @TableName nvarchar(100), @RecordID uniqueidentifier, @OwnerID uniqueidentifier, @AccessFieldName nvarchar(20), @AccessFieldValue int WITH EXECUTE AS OWNER as begin set nocount on if @TableName is Null OR @RecordID is NULL OR @OwnerID is Null OR @AccessFieldName is NULL OR @AccessFieldValue is NULL return declare @AuOwnerID uniqueidentifier SET @AuOwnerID = (SELECT ID FROM tbl_AdminUnit WHERE UserContactID = @OwnerID) IF @AuOwnerID IS NULL return begin tran execute ('update '+@TableName+' set '+@AccessFieldName+'='+@AccessFieldValue+ ' where RecordID='''+@RecordID+''' and AdminUnitID='''+@AuOwnerID+'''') if @@rowcount = 0 begin declare @CanRead int declare @CanWrite int declare @CanDelete int declare @CanChangeAccess int set @CanRead = 0 set @CanWrite = 0 set @CanDelete = 0 set @CanChangeAccess = 0 execute('set @'+@AccessFieldName+'='+@AccessFieldValue); execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+ 'VALUES (NewID(), @RecordID, @AuOwnerID, @CanRead, @CanWrite, @CanDelete, @CanChangeAccess)') end commit tran end
Также, я дал доступ всем пользователям на выполнение этой хранимой процедуры:
GRANT execute ON [dbo].[tsp_SetRightsToRecordForUser] TO public
Пример вызова хранимой процедуры:
EXEC [dbo].[tsp_SetRightsToRecordForUser] 'tbl_AccountRight', '{00DF9C8D-9399-49BE-89A8-078DB4CA093F}', '{251FB9AC-C17E-4DF7-A0CB-D591FDB97462}', 'CanRead', 1
У меня почему-то возникают следующие ошибки:
Msg 137, Level 15, State 1, Line 1 Must declare the scalar variable "@CanRead". Msg 137, Level 15, State 2, Line 1 Must declare the scalar variable "@RecordID".
Может кто знает в чем проблема?
Здравствуйте, Андрей.
Скорее всего, проблема в том, что вот этот execute
execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+ 'VALUES (NewID(), @RecordID, @AuOwnerID, @CanRead, @CanWrite, @CanDelete, @CanChangeAccess)')
не видит параметров @CanRead, @CanWrite, @CanDelete, @CanChangeAccess.
Попробуйте сделать следующим образом:
execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+ 'VALUES (NewID(), '''+@RecordID+''', '''+@AuOwnerID+''', 0, 0, 0, 0)')
Инна Безверхняя,
II линия службы поддержки Terrasoft
Переделал вот так и заработало без ошибок:
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go CREATE procedure [dbo].[tsp_SetRightsToRecordForUser] @TableName nvarchar(100), @RecordID uniqueidentifier, @OwnerID uniqueidentifier, @AccessFieldName nvarchar(20), @AccessFieldValue int WITH EXECUTE AS OWNER as begin set nocount on if @TableName is Null OR @RecordID is NULL OR @OwnerID is Null OR @AccessFieldName is NULL OR @AccessFieldValue is NULL return declare @AuOwnerID uniqueidentifier SET @AuOwnerID = (SELECT ID FROM tbl_AdminUnit WHERE UserContactID = @OwnerID) IF @AuOwnerID IS NULL return begin tran execute ('update '+@TableName+' set '+@AccessFieldName+'='+@AccessFieldValue+ ' where RecordID='''+@RecordID+''' and AdminUnitID='''+@AuOwnerID+'''') if @@rowcount = 0 begin if @AccessFieldName = 'CanRead' execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+ 'VALUES (NewID(), '''+@RecordID+''', '''+@AuOwnerID+''', '+@AccessFieldValue+', 0, 0, 0)') if @AccessFieldName = 'CanWrite' execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+ 'VALUES (NewID(), '''+@RecordID+''', '''+@AuOwnerID+''', 0,'+@AccessFieldValue+', 0, 0)') if @AccessFieldName = 'CanDelete' execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+ 'VALUES (NewID(), '''+@RecordID+''', '''+@AuOwnerID+''', 0, 0, '+@AccessFieldValue+', 0)') if @AccessFieldName = 'CanChangeAccess' execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+ 'VALUES (NewID(), '''+@RecordID+''', '''+@AuOwnerID+''', 0, 0, 0, '+@AccessFieldValue+')') end commit tran end