Как записать строки в PL/SQL курсор в определенном порядке
Не понимаю, как записать в курсор строки в определенном (заданным некоторым условием) порядке.
Т.е. интересующая строка должна попасть в результат select-а в любом случае, но требуется, чтобы она была именно последней в курсоре. Нужную сортировку подабрать не удалось, условие поставновки на последнее место определяется значением, которое лежит в одном из полей этой строки (в примере ниже условие s.service_synonym = 'AutoCloseOrder')
Пробовал через union, но он все равно не помещает нужную строку в конец курсора
create or replace procedure get_service2(p_document_id number, res out sys_refcursor)
is
begin
open res for
select s.service_id, s.service_synonym from document d
join service s on d.service_id = s.service_id
where d.document_id = p_document_id and (s.service_synonym <> 'AutoCloseOrder' or s.service_synonym is null)
union
select s.service_id, s.service_synonym from document d
join service s on d.service_id = s.service_id
where d.document_id = p_document_id and s.service_synonym = 'AutoCloseOrder';
--order by s.service_synonym desc;
end get_service2;
Ответы (1 шт):
Это ошибка, считать, что запись последнего подзапроса в UNION будет выведена последней.
UNION неявно сортирует предварительный результат по всем в нём присутствующим колонкам с целью устранения дубликатов.
Хорошо, но многие знают об этом и выключают неявное устранение дубликатов с UNION ALL. В этом случае, результат вроде выглядит, как ожидаемый (допустим нас интересует строка name=b):
create table t (id primary key, name) as
select rownum, trim (column_value) from xmlTable ('"a"," ", "b","c"')
/
select t.* from t where name!='b'
union all
select t.* from t where name='b'
/
ID NAME
---------- ----
1 a
4 c
3 b
Но это ещё худшая ошибка, потому что порядок записей этого результата не гарантируется, ни стандартом SQL, ни документацией. Другими словами, сегодня порядок такой, завтра другой.
Порядок записей в результате запроса гарантируется только с ORDER BY, исключений нет:
select *
from t
order by case name when 'b' then 1 else 0 end, id
/
ID NAME
---------- ----
1 a
3 c
2 b