Я заранее прошу прощения за мой скучный вопрос, и если форматирование не соответствует номиналу (новичок), то здесь.
У меня есть таблица MY_TABLE со следующей схемой -
MY_ID | TYPE | REC_COUNT
1 | A | 1
1 | B | 3
2 | A | 0
2 | B | 0
....
Первый столбец соответствует идентификатору, второй - некоторому типу, а третий - некоторому.Обратите внимание, что столбец MY_ID не является первичным ключом, может быть много записей с одинаковым MY_ID.
Я хочу написать хранимую процедуру, которая будет принимать массив идентификаторов и возвращать их подмножество, соответствующееследующие критерии - идентификатор должен совпадать с полем MY_ID, по крайней мере, 1 записи в таблице, и, по крайней мере, 1 соответствующая запись не должна иметь TYPE = A ИЛИ REC_COUNT = 0.
Это процедура, которую я придумал -
PROCEDURE get_id_subset(
iIds IN ID_ARRAY,
oMatchingIds OUT NOCOPY ID_ARRAY
)
IS
BEGIN
SELECT t.column_value
BULK COLLECT INTO oMatchingIds
FROM TABLE(CAST(iIds AS ID_ARRAY)) t
WHERE EXISTS (
SELECT /*+ NL_SJ */ 1
FROM MY_TABLE m
WHERE (m.my_id = t.column_value)
AND (m.type != 'A' OR m.rec_count != 0)
);
END get_id_subset;
Но я действительно беспокоюсь о производительности, и некоторые идентификаторы могут соответствовать тысячам записей в таблице.Существует индекс для столбца MY_ID и TYPE, но нет индекса для столбца REC_COUNT.Поэтому я подумал, что если есть более 1000 строк с совпадающим полем MY_ID, я просто верну идентификатор без применения предикатов TYPE и REC_COUNT.Вот эта версия -
PROCEDURE get_id_subset(
iIds IN ID_ARRAY,
oMatchingIds OUT NOCOPY ID_ARRAY
)
IS
BEGIN
SELECT t.column_value
BULK COLLECT INTO oMatchingIds
FROM TABLE(CAST(iIds AS ID_ARRAY)) t, MY_TABLE m
WHERE (m.my_id = t.column_value)
AND ( ((SELECT COUNT(m.my_id) FROM m WHERE 1) >= 1000)
OR EXISTS (m.type != 'F' OR m.rec_count != 0)
);
END get_id_subset;
Но это не компилируется, я получаю следующую ошибку при внутреннем выборе -
PL / SQL: ORA-00936: отсутствует выражение
Есть ли другой способ написать это?Внутренний выбор должен работать с объединенной таблицей.
И чтобы уточнить, я согласен с набором результатов, отличающимся для этого запроса.Я предполагаю, что, поскольку в столбце my_id есть индекс, выполнение count (*) будет намного дешевле, чем фактическое применение предиката rec_count к 10000s строк, поскольку в этом столбце нет индекса.Я не прав?