SQL хранимые процедуры и побитовые операторы - PullRequest
1 голос
/ 06 июня 2011

У меня есть таблица категорий:

    id;description;special
    ----------------------
    1;Spares;TRUE
    2;Accessories;TRUE
    4;Consumables;TRUE
    8;Services;TRUE
    11;Printer;FALSE
    12;Monitor;FALSE
    13;Other;FALSE

Специальное поле обозначает специальные категории, которые имеют фиксированные идентификаторы и не могут быть удалены или изменены. Я назначил для них побитовые OR-способные идентификаторы.

Тогда у меня есть предметы, каждый предмет относится к категории (с отношением 1: n).

Теперь я хотел бы написать хранимую процедуру, которая принимает входной параметр, содержащий комбинацию идентификаторов OR-ed:

1 I want spare parts
2 I want accessories
4 I want consumables 
**5 I want consumables AND spare parts**

и т.д.

Если параметр НЕДЕЙСТВИТЕЛЕН, тогда я хочу каждый элемент независимо от его категории.

Это довольно просто, скажем, параметр называется _or_category, тогда предложение WHERE может выглядеть примерно так:

SELECT
    *
FROM
    items I 
JOIN 
    categories C ON (C.id = I.category)
WHERE
    (_or_category IS NULL) OR (C.special = TRUE AND C.id | _or_categoria = _or_categoria)
;

Первая проблема: * edit: извините, это не проблема, поскольку в предложении WHERE указано C.special = TRUE. * категорию 12 можно «увидеть» как id = 8 ИЛИ 4, поэтому, если я хочу выбрать только расходные материалы, я бы также получил мониторы!

Вторая проблема: Я не знаю, как указать, когда мне нужны все элементы, которые НЕ являются услугами (cat: 8).

Ответы [ 2 ]

1 голос
/ 06 июня 2011

Вам нужно

0x01 - Spares
0x02 - Accessories
0x04 - Consumables
0x08 - Services
0x10 - Printer
0x20 - Monitor
0x40 - Other

И все, кроме услуг = 0x7F & ~0x08

Редактировать: Если вы хотите, чтобы только первые 4 вещи были флагами, это не сильно отличается.Первые 4 бита зарезервированы исключительно для сравнения ваших битов.Таким образом, у вас не может быть никаких дополнительных идентификаторов, которые потребовали бы значение в первых 4 битах (справа) ...

0x01 - Spares
0x02 - Accessories
0x04 - Consumables
0x08 - Services
0x10 - Printer
0x20 - Monitor
0x30 - Other

И снова Ax(~Sx) = 0x3F & ~0x08

1 голос
/ 06 июня 2011

Вторая проблема: я не знаю, как укажите, когда я хочу все элементы которые НЕ являются услугой (кошка: 8)

Если я понимаю ваш вопрос, я думаю, что вы ищете битовые инвертируемые биты ~

например

C.special = TRUE AND  (~C.ID | or_categoria = _or_categoria)
...