Есть СУБД FireBird версии 2.0.x.
Есть таблица, в которой одним из полей хранится битовая карта дней недели.
Задача: проверить, входит ли день недели (номер 1-7) в битовую карту.
Я понимаю, что в СУБД FireBird 2.1.x были введены операции BIT_xx, но использовать пока приходится только FireBird 2.0.x.
Вот моё решение (отмечу, что MATCH=NULL тождественно всем дням недели, установленным в 1):
SET TERM ^ ; -- Validate week day match -- param: _MASK - week day mask -- param: _VALUE - day of month (1-7) -- return: _RESULT - match result: match type or NULL if no match CREATE OR ALTER PROCEDURE FN_SCHEDULED_WEEKDAY_MATCH ( "_MASK" INTEGER, "_VALUE" INTEGER ) RETURNS ( "_RESULT" INTEGER ) AS DECLARE VARIABLE "_TEST" INTEGER; BEGIN IF ("_MASK" IS NOT NULL) THEN BEGIN -- Binary functions are available only in FB 2.1, need to make workaround "_MASK" = "_MASK" + 128; -- For comparisons IF (("_VALUE" = 1) AND ((("_MASK"-1)/2) = ("_MASK"/2))) THEN -- Monday "_RESULT" = 1; ELSE IF (("_VALUE" = 2) AND ((("_MASK"-2)/4) = ("_MASK"/4))) THEN -- Tuesday "_RESULT" = 1; ELSE IF (("_VALUE" = 3) AND ((("_MASK"-4)/8) = ("_MASK"/8))) THEN -- Wednesday "_RESULT" = 1; ELSE IF (("_VALUE" = 4) AND ((("_MASK"-8)/16) = ("_MASK"/16))) THEN -- Thursday "_RESULT" = 1; ELSE IF (("_VALUE" = 5) AND ((("_MASK"-16)/32) = ("_MASK"/32))) THEN -- Friday "_RESULT" = 1; ELSE IF (("_VALUE" = 6) AND ((("_MASK"-32)/64) = ("_MASK"/64))) THEN -- Saturday "_RESULT" = 1; ELSE IF (("_VALUE" = 7) AND ((("_MASK"-64)/128) = ("_MASK"/128))) THEN -- Sunday "_RESULT" = 1; END ELSE "_RESULT" = 0; -- Suspend for select SUSPEND; END^ SET TERM ; ^ |
Есть предложения лучше?
Использовать udf.
Да, видел такую возможность и воспользовался, когда нужно было.
Благодарю.