CREATE TABLE PERMISSOES (
OBJETO VARCHAR2(100),
USUARIO VARCHAR2(100)
)
Eu preciso de um relatório que enumere todos os usuários para cada objeto, colocando todos os autorizados numa só linha. A minha solução, um pouco complicada, foi juntar as facilidades de consultas hierárquicas do Oracle com um pouco de funções analíticas.O cerne da consulta é o seguinte SELECT:
select objeto,
row_number() over (partition by objeto order by usuario) ordem,
row_number() over (partition by objeto order by usuario desc) medro,
usuario
from permissoes
order by 1, 2, 3 desc
Isso produz uma lista de todos os objetos com os respectivos usuários numerados alfabeticamente tanto crescentemente como decrescentemente. Considere as seguintes linhas:| OBJETO | USUARIO |
| COFRE | Heráclito |
| COFRE | Xenofonte |
| COMPUTADOR | Heródoto |
| COMPUTADOR | Heráclito |
| COMPUTADOR | Platão |
A consulta produzirá o resultado abaixo:
| OBJETO | ORDEM | MEDRO | USUARIO |
| COFRE | 1 | 2 | Heráclito |
| COFRE | 2 | 1 | Xenofonte |
| COMPUTADOR | 1 | 3 | Heráclito |
| COMPUTADOR | 2 | 2 | Heródoto |
| COMPUTADOR | 3 | 1 | Platão |
Envolvendo essa consulta com um SELECT hierárquico, podemos agregar os helenos.
select objeto, substr(sys_connect_by_path(usuario, ','),2) autorizados
from (
select objeto,
row_number() over (partition by objeto order by usuario) ordem,
row_number() over (partition by objeto order by usuario desc) medro,
usuario
from permissoes
)
where medro=1
connect by prior ordem=ordem-1 and prior objeto=objeto
start with ordem=1
Então, uso a coluna ORDEM para simular uma hierarquia e a coluna MEDRO para eliminar todas as linhas exceto a última (que possui todos os usuarios relacionados a um objeto).O resultado é o seguinte:
| OBJETO | AUTORIZADOS |
| COFRE | Heráclito,Xenofonte |
| COMPUTADOR | Heráclito,Heródoto,Platão |
A função sys_connect_by_path() aglutina toda a hierarquia e neste caso indiquei uma vírgula como separador. No entanto, ela coloca uma vírgula também no início e para resolver isso adicionei a função substr().

Nenhum comentário:
Postar um comentário