Вопрос знатокам СУБД Firebird.

Октябрь 29th, 2009 по SadKo Оставить ответ »

Есть СУБД 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 ; ^

Есть предложения лучше?

Реклама

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

  1. тм:

    Использовать udf.

  2. Да, видел такую возможность и воспользовался, когда нужно было.
    Благодарю.

Добавить комментарий