Может многие меня не поддержат. Но у меня стояла задача разблокировать редактирование, при этом оставив просмотр для остальных. Оставлять одну только проверку версии казалось мало, а реализовывать через транзацию побоялся: неизвестно как будет себя вести изоляция, если ею раньше не пользовался.
Реализация была через три дополнительных поля и пару процедур. Три на самом деле избыточно. Хватило бы и два. В общем этакий велосипед.
Поля в заголовке:
- Идентификатор пользователя UserEditGUID uniqueidentifier
- Дата когда пользователь начал редактировать BeginEdit datetime
- Не особо нужное поле isEdit bit
И собственно процедура блокировки:
ALTER PROCEDURE [dbo].[LockUnLockOrder]
@HeadGUID uniqueidentifier, @UserGUID uniqueidentifier, @Lock bit
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if @HeadGUID is null or @UserGUID is null or @Lock is null
begin
raiserror('Процедура LockUnLockOrder: Неинициализированный параметр',16,1)
return -1
end
if V_ORDER.dbo.CheckEditStatus(@HeadGUID,@UserGUID) = 1
begin
if @Lock = 1
UPDATE [V_ORDER].[dbo].[OrderHeader]
SET isEdit = 1
,BeginEdit = getdate()
,UserEdit = @UserGUID
WHERE GUID = @HeadGUID
else
if @Lock = 0
UPDATE [V_ORDER].[dbo].[OrderHeader]
SET isEdit = 0
,BeginEdit = null
,UserEdit = null
WHERE GUID = @HeadGUID
return 1
end
else raiserror('Невозможно изменить статус заказа',16,1)
end
И функция проверки возможности редактирования. Если пользователь открыл час назад, и не закрыл, то разрешение на редактирование выдается.
-- =============================================
-- Author: k1lex
-- Create date: 20160818
-- Description: функция возвращает разрешение редактирования заказа. 1 - можно редактировать. 0 - нельзя
-- =============================================
ALTER FUNCTION [dbo].[CheckEditStatus]
(
-- Add the parameters for the function here
@HeadGUID uniqueidentifier, @UserGUID uniqueidentifier
)
RETURNS bit
AS
BEGIN
DECLARE @bit BIT
IF (
SELECT COUNT(*)
FROM [V_ORDER].[dbo].[OrderHeader] O WITH (NOLOCK)
WHERE O.GUID = @HeadGUID
AND (ISNULL(O.IsReadOnly, 0) = 1 OR (O.userEdit != @UserGUID AND O.IsEdit = 1 AND DATEDIFF(HOUR, BeginEdit, GETDATE()) < 1)
and [Status]=1
)
) = 0
SET @bit = 1
ELSE
SET @bit = 0
RETURN @bit
END
И поддержу
Петр , что нужна проверка даты последнего изменения. На тот случай, если кто-то откроет, и вспомнит через три часа что открыл и отредактирует уже отредактированное.