Wyłuskanie bitów w klauzuli WHERE

0

Witam

Mam pytanie odnośnie wyciągania bitów z pól w bazie. Rzecz dotyczy Firebird'a 1.5. Mam pole typu INT w którym zaszytych jest kilka informacji naraz (jako kolejne bity). Chciałbym jest wyciągnąć i zawarunkować ich występowanie w WHERE'rze.

Nie chcę pisać UDF'a, bo rzecz jest dość pilna, a w tej aplikacji nie ma jeszcze żadnego UDF'ika, co się wiąże z przerabianiem setup'u, rozsyłaniem dll'ki do tych co już mają zainstalowane itd... <- generalnie to by była ostateczność.

Pytanie więc brzmi czy są jakieś operatory do operacji na bitach ? W sumie tak mi przychodzi do głowy, że mogę tego INT'a dzielić przez kolejne potęgi dwójki od największej i sprawdzać wynik i reszte z dzielenia dalej dzielić ... ale to raczej nie tędy droga.

Szukam czegoś takiego jak AND

(STATUS AND 4) = 4, tylko żeby to AND było bitowe.

No i oczywiście żeby to było szybkie.

Ale wydaje mi się że FB nie ma czegoś takiego : ( Więc wyprzedzająco zapytam, co byście proponowali zastępczego za te bit'y ? Bo rzecz wygląda tak, że ja to pole bitowe mam w jednej bazie, i chce je przenieść do drugiej bazy, ale nie chce mieć tam też pola bitowego, jak nie bede miał z niego żadnego
pozytku. Może na etapie przenoszenia zamienić to na jakiegoś string'a albo coś ...

Pozdrawiam

0

z pliku udf\ib_udf.sql

/*****************************************
*

  • b i n _ a n d

  • Functional description:
  • Returns the result of a binary AND
  • operation performed on the two numbers.

*****************************************/
DECLARE EXTERNAL FUNCTION bin_and
INTEGER, INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT 'IB_UDF_bin_and' MODULE_NAME 'ib_udf';

/*****************************************
*

  • b i n _ o r

  • Functional description:
  • Returns the result of a binary OR
  • operation performed on the two numbers.

*****************************************/
DECLARE EXTERNAL FUNCTION bin_or
INTEGER, INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT 'IB_UDF_bin_or' MODULE_NAME 'ib_udf';

/*****************************************
*

  • b i n _ x o r

  • Functional description:
  • Returns the result of a binary XOR
  • operation performed on the two numbers.

*****************************************/
DECLARE EXTERNAL FUNCTION bin_xor
INTEGER, INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT 'IB_UDF_bin_xor' MODULE_NAME 'ib_udf';

reszty się domyśl sam :p

zapomniałem - trzymanie tak ustawiń (znaczników) jest wg mnie złym rozwiązaniem bo ani sobie tego nie poindeksujesz, przy dużej ilości danych wyciąganie bitów trochę trwa. Ja bym po prostu wstawił to do osobnych kolumn jednoznakowych (bool jeśli baza ma) albo na upartego zrobił jedną znakową o rozmiarze takim ile jest tych znaczników

0
Misiekd napisał(a)

z pliku udf\ib_udf.sql ...

Wielka dziękówa, tak to czasem jest że się szuka daleko jak się ma blisko. Co prawda problem rozwiązałem inaczej, ale docelowo wykorzystam chyba tego bit_and'a.

Misiekd napisał(a)

zapomniałem - trzymanie tak ustawiń (znaczników) jest wg mnie złym rozwiązaniem bo ani sobie tego nie poindeksujesz, przy dużej ilości danych wyciąganie bitów trochę trwa.

Też mi się to nie podoba, kiedyś przyczyną takich posunięć była pewnie chęć zaoszczędzenia miejsca. Ale tak się zastanawiam, to ten bit_and nie powinien być jakoś specjalnie wolny, zapewne ciało tej funkcji kryje 1 linijkę w stylu Result := aData and aBitNo; więc nie jest to jakoś specjalnie "mocożerne". Od biedy index na tym polu założyć można : ) tylko co to da ?

Misiekd napisał(a)

Ja bym po prostu wstawił to do osobnych kolumn jednoznakowych (bool jeśli baza ma)

Takie rozwiązanie jest na pewno najbardziej wygodne/wydajne bo można założyć indeksiki itd. Ale tak się zastanawiałem, że stosowanie tego bit_and'a jest też spoko w tej sytuacji jaką mam.

Misiekd napisał(a)

albo na upartego zrobił jedną znakową o rozmiarze takim ile jest tych znaczników

Tylko jak byś to widział, to miało by być coś w stylu '010011100' ? Ale jak potem testować czy jest ustawiony jakiś bit ? Substringiem ? jeśli tak to wydaje mi sie że będzie to wolniejsze od bit_and'a.

Pozdrawiam

0
b0bik napisał(a)

Tylko jak byś to widział, to miało by być coś w stylu '010011100' ? Ale jak potem testować czy jest ustawiony jakiś bit ? Substringiem ? jeśli tak to wydaje mi sie że będzie to wolniejsze od bit_and'a.

Tak logicznie rzecz biorac, przyrownujac taka operacje np. w c to

int a = wynik & 1>>bit;

niewiele sie rozni szybkoscia od

int a = charTable[bit]? 1: 0;

Ja bym raczej nie przesadzal i zrobil to osobnymi kolumnami. Pamietaj, ze to zmartwieniem silnika jest tak upakowac dane, zeby bylo szybko i przyjemnie. I zazwyczaj robi to lepiej, jezeli stosujesz bazodanowe podejscie (kolumny i odpowiednie typy - wtedy wie z czym ma do czynienia) niz starasz sie przechytrzyc ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1