Как изменять значение поля по БП, не давая доступ на изменение записи
Подскажите кто как решает задачу, когда по БП под пользователем (например, после отработки задачи), который не имеет прав на изменение записи документа, нужно изменить состояние документа?
Тут или каждый раз создавать хранимую процедуру, специфически для изменения поля в записи, но тогда функционал обработки событий датасета не будет отрабатывать. Или давать доступ на изменение на запись, что тоже имеет свои минусы, поскольку пользователь получает полный доступ к изменению записи вручную.
Нравится
можно сделать грязный хак - изменение делать через customsql и таблице в бд дать права доступа - на видимости в системе это не отобразится и, имхо, пользователь не проведай и сим разрешением воспользоваться не сможет
Здравствуйте, Андрей!
А если попробовать таким образом, в одном элементе процесса последовательно выполнять 3 действия:
1. вызывать хранимую процедуру, которая раздаст права текущему пользователю на изменение данного документа;
2. вызывать событие изменения поля состояния документа и сохранять его;
3. вызывать хранимую процедуру, которая забирает у пользователя право на изменение этого документа.
Причем, можно раздавать право на изменение только одного поля. Так пользователь и злоупотребить этим не сможет и функционал обработки событий датасета должен отработать корректно.
Инна Безверхняя,
II линия службы поддержки Terrasoft
Спасибо Алексей и Инна за ответ.
Инна, мне ваш совет кажется наиболее подходящим, действительно - можно доработать элемент БП чтения/записи данных так, как вы написали.
Вот такую хранимую процедуру я написал, которая является универсальной для дачи или забирания права на какое-то одно действие с записью (право на чтение, изменение, удаление или изменение доступа к записи).
[sql]
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
[/sql]
Также, я дал доступ всем пользователям на выполнение этой хранимой процедуры:
[sql]
GRANT execute ON [dbo].[tsp_SetRightsToRecordForUser] TO public
[/sql]
Пример вызова хранимой процедуры:
[sql]
EXEC [dbo].[tsp_SetRightsToRecordForUser] 'tbl_AccountRight', '{00DF9C8D-9399-49BE-89A8-078DB4CA093F}', '{251FB9AC-C17E-4DF7-A0CB-D591FDB97462}', 'CanRead', 1
[/sql]
У меня почему-то возникают следующие ошибки:
[sql]
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".
[/sql]
Может кто знает в чем проблема?
Здравствуйте, Андрей.
Скорее всего, проблема в том, что вот этот execute
[sql]
execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+
'VALUES (NewID(), @RecordID, @AuOwnerID, @CanRead, @CanWrite, @CanDelete, @CanChangeAccess)')
[/sql]
не видит параметров @CanRead, @CanWrite, @CanDelete, @CanChangeAccess.
Попробуйте сделать следующим образом:
[sql]
execute ('insert into '+@TableName+' (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess)'+
'VALUES (NewID(), '''+@RecordID+''', '''+@AuOwnerID+''', 0, 0, 0, 0)')
[/sql]
Инна Безверхняя,
II линия службы поддержки Terrasoft
Переделал вот так и заработало без ошибок:
[sql]
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
[/sql]