Как изменять значение поля по БП, не давая доступ на изменение записи

Подскажите кто как решает задачу, когда по БП под пользователем (например, после отработки задачи), который не имеет прав на изменение записи документа, нужно изменить состояние документа?

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

Нравится

7 комментариев

можно сделать грязный хак - изменение делать через 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
Показать все комментарии