Вчера меня перло и поэтому я сделал проверку временного периода на валидность - тоесть проверяет действует ли выбраный период в текущее время. Вот код функций:
Первая для получения значения бита из переменной с областью значений байта (254...0):
Код:
CREATE FUNCTION [gk].[GetBit] (@val int,@bit int) RETURNS bit AS
BEGIN
DECLARE @out bit = 0
DECLARE @i int = 7
WHILE @i >= 0 BEGIN
IF(@val >= POWER(2,@i)) BEGIN
SET @val -= POWER(2,@i)
IF(@i = @bit)BEGIN SET @out = 1 END
END
SET @i -= 1
END
RETURN @out
END
И вторая сама проверка периода, возвращает число совпавших интервалов в данном периоде - ноль если нет совпадений. Если периоды составлены из не пересекающихся временнных интервалов то будет возвращать 1 если период действителен.
Код:
CREATE FUNCTION [gk].[CheckPeriod] (@period int) RETURNS int AS
BEGIN
DECLARE @TIME int = DATEPART(HOUR, GETDATE())*60 + DATEPART(MINUTE, GETDATE())
DECLARE @out int = (SELECT count(*)
FROM [gkArcade].[gk].[PERIODDETAILS]
WHERE ([PERIOD] = @period)AND([STATUS] = 3)AND(IIF(([STARTTIME]<= @TIME)AND([ENDTIME] >= @TIME),32*gk.GetBit([DATEFLAGS],5),0)+
IIF((gk.Getbit([DAYSOFWEEK],DATEPART(weekday,GETDATE())) = 1),gk.GetBit([DATEFLAGS],0),0)+
IIF(([STARTDATE]<=GETDATE())AND([ENDDATE]>=GETDATE()),16*gk.GetBit([DATEFLAGS],4),0)+
IIF((DATEADD(year,YEAR(GETDATE())-YEAR([STARTDATE]),[STARTDATE])<=GETDATE())AND(DATEADD(year,YEAR(GETDATE())-YEAR([ENDDATE]),[ENDDATE])>=GETDATE())AND(gk.GetBit([DATEFLAGS],3)=1),8*gk.GetBit([DATEFLAGS],3)+4*gk.GetBit([DATEFLAGS],2)+2*gk.GetBit([DATEFLAGS],1),0)+
IIF((DAY([STARTDATE])<=DAY(GETDATE()))AND(DAY([ENDDATE])>=DAY(GETDATE()))AND(gk.GetBit([DATEFLAGS],3) = 0)AND(gk.GetBit([DATEFLAGS],4) = 0),6*gk.GetBit([DATEFLAGS],1)*gk.GetBit([DATEFLAGS],2),0) = [DATEFLAGS] ))
RETURN @out
END
Пример:
Код:
SELECT * FROM [gkArcade].[gk].[GK_BONUSES] WHERE [gkArcade].[gk].CheckPeriod([PERIOD])>0
Покажет ВСЕ действующие по времени бунусы.
И код обнуляющий бонусы с транзакциями - через курсор
Считается что ид 2 у пользователя админ - транзакции от его имени
Код:
DECLARE @CARD int
DECLARE @Level int
DECLARE @Bonus money
DECLARE upd CURSOR READ_ONLY FOR
SELECT [CARD],[Bonus],[Level] FROM [gkArcade].[gk].[GK_CARDS]
WHERE DATEADD(day,90,[CardLastUse]) < GETDATE() --карты не активные 90
OPEN upd
FETCH NEXT FROM upd INTO @CARD,@Bonus,@Level
WHILE (@@FETCH_STATUS <> -1) BEGIN --Операция "Списание бонусов" ид 850
INSERT INTO [gkArcade].[gk].[TRANSACTS] ([DATE],[ACCOUNT],[EMPLOYEE],[ACTIVITY],[VALUE1],[UNIT1],[VALUE2],[UNIT2],[QUANT],[CREATOR],[CREATORADDR],[CREATORDATE],[CARD],[DEAL],[CheckItem])
VALUES(GETDATE(),@CARD,2,850,1,401,@BONUS,401,1,1,1,GETDATE(),@CARD,NULL,0)
INSERT INTO [gkArcade].[gk].[GK_TRANSACTS]([DATE],[ACTIVITY],[CARD],[ACCOUNT_TYPE],[VALUE],[QUANT],[CREATOR],[CREATORADDR],[DEAL],[CHECK_ITEM],[EMPLOYEE],[LEVEL],[ARCADE],[GUID],[TRANSACT_GUID])
VALUES(GETDATE(),850,@CARD,2,-@BONUS,0,1,1,NULL,0,2,@Level,1,newid(),newid())
-- обнуляем бонус
UPDATE [gkArcade].[gk].[GK_CARDS] SET [Bonus] = 0 WHERE [Card]=@CARD
FETCH NEXT FROM upd INTO @CARD,@Bonus,@Level
END
CLOSE upd
Надеюсь данный код поможет вам реализовать вашу бизнеслогику не входящую в функционал Game Keeper