Laboratório de Laboratório de Banco de Dados Banco de Dados
Linguagens SQL e PL/SQL Linguagens SQL e PL/SQL
Prof.: Eduardo Arruda Prof.: Eduardo Arruda
Aula 5 Aula 5
Comando SELECT:
Comando SELECT:
Operadores, Funções e Operadores, Funções e
Junções
Junções
Comando
Comando SELECT SELECT
O comando SELECT é formado pelas cláusulas SELECT, FROM, WHERE, ORDER BY, GROUP BY, HAVING, START WITH...CONNECT BY, FOR UPDATE e NOWAIT. Estas cláusulas permitem recuperar dados de uma ou mais tabelas ou visões, especificar uma ou mais condições, ordenar ou computar dados por grupos de linhas, etc.
Utilização:
recuperacão de dados de um banco de dados como parte do comando de inserção
como parte do comando atualização
Comando Comando SELECT SELECT
Sintaxe:
SELECT [ALL | DISTINCT] colunas
[FROM tabelas| visões | snapshots | subconsultas, ...]
[WHERE cláusula]
[START WITH cláusula[CONNECT BY cláusula]]
[GROUP BY cláusula[HAVING cláusula]]
[ORDER BY cláusula]
[FOR UPDATE cláusula[NOWAIT]]
A A Cláusula Cláusula WHERE WHERE
A cláusula WHERE especifica critérios para determinar o conjunto de linhas a ser recuperado (seleção)
select colunas from tabelas where condições
Select nome from usuarios
where nome like 'A%';
Textos e Datas Textos e Datas
Textos e datas sempre devem ser colocados entre aspas simples (')
A comparação de textos diferencia maiúsculas e minúsculas
As datas suportam diferentes formatos de
representação
Critérios
Critérios de de Seleção Seleção de de Linhas
Linhas
Os critérios de seleção de linhas são baseados em:
Operadores de Comparação:
=, <, >, <=, >=, <>
Expressões de Intervalos:
BETWEEN … AND …
Expressões sobre Conjuntos:
IN, ANY, SOME, ALL, EXISTS
Critérios
Critérios de de Seleção Seleção de de Linhas
Linhas
Comparações por Similaridade:
LIKE
Valores Nulos:
IS [NOT] NULL
Operador IN Operador IN
É utilizado como o operador de conjuntos
“pertence”
select *
from enderecos
where cod_cidade in (12, 45, 61);
Operador LIKE Operador LIKE
Utilizado para comparações de textos por similaridade
%: representa qualquer seqüência de caracteres
_: representa um único caracter
Select *
from usuarios
Operador LIKE Operador LIKE
Muito cuidado ao utilizar o operador LIKE
Se forem utilizados os caracteres % e _ no ínicio do texto, não serão utilizados índices na consulta
Exemplos Exemplos
Seleção de linhas utilizando operadores de comparação na cláusula WHERE
Operadores de comparação
between
in
like
is [not] null
Conectivos
Conectivos Lógicos Lógicos
Os conectivos lógicos AND e OR
representam a união de duas condições.
AND
retorna um resultado quando todas as condições são verdadeiras
OR
retorna um resultado quando uma das condições é verdadeira
O conectivo lógico NOT retorna um resultado quando a condição de pesquisa é falsa.
Exemplos Exemplos
select * from usuarios
where nome like 'Carlos%' and email like '%@dell.com'
select * from produtos where importado='s' or preco > 3000;
select * from telefones
where cod_tipo_telefone not in
Conectivos Lógicos X Índices Conectivos Lógicos X Índices
Quando é utilizado o conectivo AND entre duas condições sobre colunas diferentes e as duas colunas forem indexadas,
somente um índice poderá ser utilizado
Quando é utilizado o conectivo OR, ambos os índices poderão ser utilizados
A A Cláusula Cláusula ORDER BY ORDER BY
A cláusula ORDER BY ordena os
resultados de consultas baseado em uma ou mais colunas.
A ordem pode ser crescente (ASC) ou decrescente (DESC)
Caso não seja especificada ordem
assume-se ASC, por padrão
Exemplo Exemplo
Select * from usuarios order by cpf asc;
Select * from enderecos
order by cod_cidade, cep desc, rua desc, numero
A(s) coluna(s) da cláusula ORDER BY não precisam necessariamente aparecer na cláusula SELECT
A Tabela DUAL A Tabela DUAL
A tabela DUAL é uma tabela “dummy”
Ela contém somente uma coluna chamada
“dummy” e apenas uma linha que contém o valor 'X'
Ela é utilizada sempre que se deseja
retornar uma única linha em uma consulta
Exemplos Exemplos
select * from dual;
select 'teste' texto_fixo from dual;
select sysdate from dual;
Datas Datas
Datas são armazenadas internamente como:
Ano, mês, dia, hora, minuto e segundo
Podem ser utilizados diversos formatos para as datas
SYSDATE é a função que retorna a data e
hora atuais
Operações com Datas Operações com Datas
date + number = date
date – number = date
date – date = número de dias
date + number/24 = date, com um determinado número de horas a mais
Funções Funções
Funções sobre linhas
Operam sobre cada linha do resultado individualmente
Funções sobre conjuntos de linhas
Operam sobre diversas linhas, calculando valores sobre todo o conjunto (totais, médias, o maior valor, etc.)
Funções
Funções Numéricas Numéricas
ABS(n), ACOS(n), ASIN(n), ATAN(n), ATAN2(n), CEIL(n), COS(n), COSH(n), EXP(n), FLOOR(n), LN(n), LOG(n),
MOD(n,m), POWER(n,m), ROUND(n,m), SIGN(n), SIN(n), SINH(n), SQRT(n), TAN(n), TANH(n), TRUNC(n,m)
Funções
Funções sobre sobre Caracteres Caracteres
Mudança de maiúsculas e minúsculas:
LOWER(s), UPPER(s), INITCAP(s)
Eliminação de espaços: LTRIM(s1,s2), RTRIM(s1,s2)
Outras: CONCAT(s1,s2), LPAD(s1,n,s2), RPAD(s1,n,s2), LENGTH(s),
SUBSTR(s,n,m), REPLACE(s1,s2,s3), CHR(n), SOUNDEX(s),
TRANSLATE(s1,s2,s3), etc.
Utilizando Funções Utilizando Funções
ORACLE oferece inúmeras funções:
Funções Matemáticas:
ABS(n): valor absoluto de n
Exemplo:
SELECT ABS(-15) “Valor Absoluto”
FROM DUAL;
CEIL(n): retorna o primeiro inteiro maior ou igual
Exemplo:
SELECT CEIL(18.7) "Ceil"
FROM DUAL;
Ceil ---
19
Utilizando Funções Utilizando Funções
FLOOR(n): retorna o primeiro inteiro menor ou igual
Exemplo:
SELECT FLOOR(18.7) ”Floor"
FROM DUAL;
Floor ---
18
MOD(n,m): retorna o resto de uma divisão
Exemplo:
SELECT MOD(20,3) ”Módulo"
FROM DUAL;
Utlizando
Utlizando Funções Funções
POWER(n,m): retorna uma potência
Exemplo:
SELECT POWER(3,4) “Potência"
FROM DUAL;
Potência --- 27
ROUND(n[,m]): arredonda n para m casas decimais (se omitido é zero)
Exemplo:
SELECT ROUND(18.78276,1) ”Round"
FROM DUAL;
Round --- 18.8
Utilizando Funções Utilizando Funções
TRUNC(n[,m]): trunca o resultado m casas decimais (se omitido é zero)(se menor que zero, zera dígitos a esquerda da vírgula)
Exemplo:
SELECT TRUNC(18.78276,1) ” Trunc "
FROM DUAL;
Trunc ---
18.7
Exemplo:
SELECT TRUNC(5618.78276,-2) ”Trunc"
FROM DUAL;
Trunc ---
5600
Utilizando Funções Utilizando Funções
Funções de Caracteres:
INITCAP(s): torna as iniciais maiúsculas
Exemplo:
SELECT INITCAP('joão da silva') ” Nome "
FROM DUAL;
Nome --- 'João Da Silva'
LOWER(s): passa para minúsculas
Exemplo:
SELECT LOWER('TesTE DE minÚSCUlas') ” Lower "
FROM DUAL;
Lower
--- teste de minúsculas
Utilizando Funções Utilizando Funções
LPAD(c1,n,c2): retorna a seqüência de caracteres c1, preenchida à esquerda por n caracteres c2 (se omitido são utilizados espaços em branco)
Exemplo:
SELECT LPAD('Teste',12,'*') “Lpad”
FROM DUAL;
Lpad ---
*******Teste
LTRIM(s1,s2): remove da esquerda de s1 a seqüência s2
Exemplo:
SELECT LTRIM('3434343434567890','34') “Ltrim”
FROM DUAL;
Utilizando Funções Utilizando Funções
REPLACE(s1,s2,s3): substitui s2 por s3 em s1
Exemplo:
SELECT REPLACE('Teste de Banco de Dados','Banco de Dados','Oracle')“Ltrim”
FROM DUAL;
Ltrim
--- Teste de Oracle
RPAD(c1,n,c2): equivalente ao LPAD, mas preenchendo à direita
RTRIM(s1,s2): equivalente ao RTRIM, mas removendo à direita
SUBSTR(s,n[,m]): retorna a substring de s, iniciando em n até m (se omitido vai até o final)
Utilizando Funções Utilizando Funções
SOUNDEX(s): retorna uma string com a representação fonética de s
Exemplo:
select soundex(substr(nome,1,7)) “Soundex”,nome “Nome”
from alunos
where soundex(substr(nome,1,7)) = soundex('André') order by 1
Soun Nome
--- --- A536 Andre Madeira
A536 André Antoniazzi A536 Anderson de Oliveira A536 André Trein
Utilizando Funções Utilizando Funções
UPPER(s): passa para maiúsculas
INSTR(s1,s2[,n[,m]]): retorna a posição de s1 em que ocorre s2, iniciando a busca em n e finalizando em m
Exemplo:
select INSTR('Teste especial','es'] “Posição”
from dual;
Posição --- 2
LENGHT(s): retorna o tamanho de s
Utilizando Funções Utilizando Funções
Funções de Data e Hora
ADD_MONTHS(d,n): adiciona n meses na data d
Exemplo:
select ADD_MONTHS('21-mar-98',5] “Data”
from dual;
Data --- 21-AUG-98
ROUND(d[,f]): formata a data d de acordo com f (se omitido, formata como dia)
Exemplo:
select ROUND('21-mar-98'] “Data”
from dual;
Utilizando Funções Utilizando Funções
Funções de Conversão
TO_CHAR(d[,f]): converte para caracteres a expressão n segundo o formato f
Exemplo:
select TO_CHAR('21-mar-98','DD, Month, YYYY') “Data”
from dual;
Data
--- 21, March , 1998
TO_DATE(s[,f]): converte a expressão s para data
Exemplo:
select to_date('March 21, 1998, 11:00 A.M.', 'Month dd, YYYY, HH:MI A.M.') “Data” from dual;
Data --- 21-MAR-98
Utilizando Funções Utilizando Funções
Outras Funções
NVL(expr1,expr2): se expr1 for nula, retorna expr2
Exemplo:
select nome “Nome”, NVL(carga_horaria,0) “Carga Horária”
from Disciplinas order by 1;
UID e USER: retornam, respectivamente, o identificador único e o nome do usuário (login) conectado ao SGBD Oracle
Exemplo:
select UID, USER from dual;
UID USER
--- --- 12 ALUNO1
Função TRUNC Função TRUNC
Select trunc(preco*1.2379,2) from produtos;
Select trunc(preco*1.2379,0) from produtos;
Select trunc(preco*1.2379,-1) from produtos;
Funções
Funções de Conversão de Conversão
O Oracle converte automaticamente em atribuições:
Varchar2 e char para number
Varchar2 e char para date
Number para varchar2
Date para varchar2
Desde que seja possível
Funções
Funções de Conversão de Conversão
O Oracle converte implicitamente em expressões:
Varchar2 e char para number
Varchar2 e char para date
Funções
Funções de Conversão de Conversão
As principais funções de conversão são:
TO_CHAR(<number ou date>, <formato>)
TO_NUMBER(<char ou varchar2>)
TO_DATE(<char ou varchar2>, <formato>)
Formatos de Datas Formatos de Datas
YYYY, YY, Y: ano
MONTH, MON, MM, RM: mês por
extenso, abreviado, com 2 dígitos e em romanos
DDD, DD, D, DAY, DY: dia do ano, dia do mês, dia da semana (domingo = 1) e dia da semana por extenso e abreviado
Q, WW, W: quarter, semana do ano, semana do mês
Formatos de Horas Formatos de Horas
HH ou HH12, HH24: horas
MI: minutos
SS: segundos
SSSSS: segundos após a meia noite
“/”, “,”, “.”: pontuação
“texto”: pode ser inserido entre aspas
Formatos de Números Formatos de Números
9: posição numérica
0: posição numérica com 0 na máscara
L: símbolo de moeda local
.: ponto decimal
,: separador de milhar
Conversão de Datas Conversão de Datas
select to_char(sysdate, 'dd/mm/yyyy') from dual;
select to_char(sysdate,
'dd/mm/yyyy h24:mi:ss') from dual;
select to_char(sysdate, 'day, dd “ de “ month “ de “ yyyy') from dual
Conversão de Datas Conversão de Datas
to_date('21/03/1971'', 'dd/mm/yyyy')
Retorna um date a partir de uma
seqüência de caracteres, convertendo de acordo com o formato definido
É a única maneira de garantir a correção do resultado
Conversão de Números Conversão de Números
to_char(1234.679, 'L999,990.00') = 'R$ 1,234.67')
to_number('456,786.76') = 456786.76
Funções sobre Datas Funções sobre Datas
MONTHS_BETWEEN(d1,d2): retorna o número de meses entre duas datas
ADD_MONTHS(d1,n): adiciona meses em uma data
NEXT_DAY(d,'dia da semana'): encontra o próximo dia da semana a partir de uma data
LAST_DAY(d): encontra o último dia do mês da data
Funções sobre Datas Funções sobre Datas
ROUND(d): arredonda uma data
round('21-mar-71','month') = 01-apr-71
round('21-mar-71','year') = 01-jan-72
TRUNC(d): trunca uma data
trunc('21-mar-71','month') = 01-mar-71
trunc('21-mar-71','year') = 01-jan-71
Função NVL Função NVL
Converte NULL para algum valor
“operável”
nvl(NULL, 0) = 0
select nvl(importado,'x') from produtos;
Função DECODE Função DECODE
Realiza um se-então-senão sobre um valor
decode(coluna ou expressão, busca1, resultado1, busca2, resultado2, ...)
select decode(importado, 's',
'produto importado', 'n', 'produto nacional') from produtos;
Função DECODE Função DECODE
DECODE(expr,expr1,result1,expr2,result2,...,padrão): compara expr com expr1, se for igual, retorna result1, senão, compara com expr2 e assim sucessivamente. Se nenhuma comparação for verdadeira, retorna padrão.
Exemplo:
select nome Nome, decode(formacao, 'G','Graduação', 'E','Especialização', 'M','Mestrado',
'D','Doutorado',
'Desconhecida') Formacao from PROFESSORES
order by 1;
Expressões CASE Expressões CASE
CASE expressão
WHEN expressão THEN expressão_retorno ...
ELSE expressão_retorno
Expressões CASE Expressões CASE
CASE
WHEN condição THEN expressão_retorno
...
ELSE expressão_retorno
Exemplo Exemplo
select
case nivel_privilegio when 2 then 'Baixo'
when 3 then 'Médio-Baixo' when 4 then 'Médio'
when 5 then 'Médio-Alto' when 6 then 'Alto'
else 'Outros'
Exemplo Exemplo
select case
when nivel_privilegio >= 1 and nivel_privilegio <
5 then 'Baixo'
when nivel_privilegio >= 5 and nivel_privilegio <
7 then 'Médio'
when nivel_privilegio >= 7 and nivel_privilegio <
10 then 'Alto' else 'Outros' End
from administradores;
Definindo
Definindo um ALIAS para um ALIAS para uma uma Tabela Tabela
Para simplificar a escrita de consultas e/ou diferenciar colunas de tabelas diferentes com o mesmo nome, pode atribuir-se aliases aos nomes das tabelas select nome_de_coluna
from nome_de_tabela [alias]
Criando
Criando Consultas Consultas sobre sobre Múltiplas
Múltiplas Tabelas Tabelas
Para consultar dados de uma ou mais tabelas ou visões relacionadas deve-se utilizar
operações de junções (Joins)
A junção de duas ou mais tabelas é equivalente em termos de resultado final à realização do produto cartesiano, comparando o valor de certos atributos, e aplicar uma projeção e uma seleção ao resultado
A utilização de aliases em junções facilita a sua leitura
Entendendo o
Entendendo o Join Join
Em todo relacionamento há uma tabela-pai (lado 1) e uma tabela-filho (lado N)
Na implementação do relacionamento, a chave primária
estados uf : CHAR(2) nome : VARCHAR2(20) regiao : CHAR(2)
<<PK>> PK_ESTADOS()
<<Table>>
1
0..*
1
<<Non-Identifying>> 0..* cidades cod_cidade : NUMBER(4, 0) nome : VARCHAR2(40) uf : CHAR(2)
<<PK>> PK_CIDADES()
<<FK>> FK_EST_CID()
<<Table>>
Tabela Pai
Tabela Filho
Cross
Cross Join Join
A combinação de todas as linhas de uma tabela com todas da outra é chamada Produto Cartesianoou Cross Join
Exemplo
select est.uf, est.nome, cid.uf, cid.nome from estados est cross join cidades cid;
ESTADOS CIDADES
UF NOME UF NOME
AC Acre ??? MG Central de Minas
AC Acre MA Central do Maranhão
AC Acre MG Centralina
AC Acre MA Centro do Guilherme
AC Acre MA Centro Novo do Maranhão
AC Acre RO Cerejeiras
AC Acre GO Ceres
Equijoin Equijoin
Um equijoinrelaciona linhas de uma tabela com as de outra, a partir de um critério de igualdade
Normalmente esta igualdade é entre uma PK (da tabela- pai) e uma FK (da tabela-filho)
Exemplo
select est.uf, est.nome, cid.uf, cid.nome from estados est inner join cidades cid
on est.uf = cid.uf;
ESTADOS CIDADES
UF NOME UF NOME
MG Minas Gerais MG Central de Minas
MA Maranhão MA Central do Maranhão
MG Minas Gerais MG Centralina
MA Maranhão MA Centro do Guilherme
MA Maranhão MA Centro Novo do Maranhão
Natural
Natural Join Join
Um natural joiné um equijoincuja condição é
estabelecida pela igualdade entre as colunas de mesmo nome da tabela-pai e da tabela-filho
Das colunas de mesmo nome das tabelas apenas uma comporá o resultado
Exemplo
select end.rua, end.numero, end.complemento, cid.nome
from enderecos end natural join cidades cid;
Joins
Joins encadeados encadeados
Exemplo: selecione o nome do autor e o título dos livros (produtos) que escreveu
select au.nome, prod.titulo from
autores au natural join autores_produtos ap
produtos cod_produto : NUMBER(5, 0) titulo : VARCHAR2(200) ano_lancamento : DATE importado : CHAR(1) preco : NUMBER(10, 2) prazo_entrega : NUMBER(3, 0)
<<PK>> PK_PRODUTOS()
<<Check>> CHK_PROD_IMPORTADO()
<<Table>>
0..* 1 autores_produtos
cod _autor : NUM BER(4, 0) cod _produto : NUMBER(5, 0)
<<PK >> P K_AUT ORES_PRODUTOS ()
<<FK>> FK_AUT_AUTPROD()
<<FK>> FK_PRD_AUTPROD()
<<Table>>
1 0..*
autores cod _autor : NUM BER(4, 0) nome : VARCHAR2(100) descricao : VARCHAR2(1024)
<<PK>> P K_AUT ORES()
<<Table>>
Precedência de
Precedência de Joins Joins
A fim de melhor controlar a precedência de joins encadeados, devem ser utilizados parênteses
Exemplo: selecionar o nome dos clientes e o número com DDD de seus telefones
select usu.nome, tel.ddd, tel.numero from
usuarios usu inner join clientes cli
on usu.cod_usuario = cli.cod_cliente natural join telefones
Precedência de
Precedência de Joins Joins
select usu.nome, tel.ddd, tel.numero from
(
usuarios usu inner join clientes clion usu.cod_usuario = cli.cod_cliente
)
natural join telefones
select usu.nome, tel.ddd, tel.numero from
usuarios usu inner join
(
clientes cli natural join telefones)
on usu.cod_usuario = cli.cod_cliente
Outer Joins Outer Joins
Em um equijoinsomente compõem o resultado linhas da tabela-pai e da tabela-filho que tenham a condição atendida
No entanto, existem linhas não relacionadas por possuírem valor NULL na coluna FK
Em um outer joiné possível definir que todas as linhas de determinada tabela (pai ou filho) farão parte do resultado, inclusive as que forem null nas colunas da condição
Outer
Outer Joins Joins
Exemplo: selecionar o nome de todos os clientes e, quando tiverem, seus números de telefone
select usu.nome,
decode(tel.numero,
null,'Sem telefone', tel.numero)
from
usuarios usu inner join clientes cli
on usu.cod_usuario = cli.cod_cliente left outer join telefones tel
on cli.cod_cliente = tel.cod_cliente
Outer
Outer Joins Joins
select usu.nome,
decode(tel.numero,
null,'Sem telefone', tel.numero)
from
usuarios usu inner join clientes cli
on usu.cod_usuario = cli.cod_cliente natural left outer join telefones tel
Outer
Outer Joins Joins
select usu.nome,
decode(tel.numero,
null,'Sem telefone', tel.numero)
from
telefones tel natural right outer join (usuarios usu inner join clientes cli
on usu.cod_usuario = cli.cod_cliente)
Outer
Outer Joins Joins
Exemplo: selecionar os títulos de todos os produtos e o nome de todos os autores, relacionando-os quando possível
select prod.titulo, aut.nome from
(produtos prod natural left outer join autores_produtos) natural right outer join autores aut
Outer
Outer Joins Joins
Para incluir todas as linhas relacionadas ou não na consulta, pode-se empregar um full outer join
Exemplo: se houvessem estados sem cidades e cidades sem estado
select est.nome, cid.nome
from estados est full outer join cidades cid on est.uf = cid.uf
Self Self Join Join
Um self joinrelaciona as linhas de uma tabela com outras linhas desta mesma tabela
Exemplo
select d2.nome
from diretorios d1 inner join diretorios d2 on d1.cod_diretorio = d2.cod_diretorio_pai where d1.nome = 'Windows'
diretorios cod_diretorio : NUMBER(5, 0) nome : VARCHAR2(255) cod_diretorio_pai : NUMBER(5, 0)
<<PK>> pk_diretorios()
<<FK>> fk_dir_dirpai()
0.. *
0..1
0.. *
0..1 <<Non-Identifying>>
Consultas Hierárquicas Consultas Hierárquicas
O Oracle permite que dados hierárquicos sejam apresentados de acordo com sua estrutura, através das cláusulas START WITH e
CONNECT BY
START WITH: especifica a condição a ser atendida pelo nós raízes
CONNECT BY: especifica a condição que relaciona um nó de nível n a um anterior de nível n-1
PRIOR: identifica as colunas do nó de nível anterior A metacoluna LEVEL identifica o nível do nó
atual
Exemplos Exemplos
Descendo na hierarquia
select
level, lpad(' ',(level-1)*3) || nome nome from diretorios
start with cod_diretorio_pai is null
connect by cod_diretorio_pai = prior cod_diretorio;
Subindo na hierarquia
select
level, lpad(' ',(level-1)*3) || nome nome from diretorios
start with cod_diretorio = 89
connect by cod_diretorio = prior cod_diretorio_pai;
Descendo...
Descendo...
SQL> set heading off SQL> set linesize 1000 SQL> set pagesize 0
SQL> column nome format a355
1 Arquivos de programas 2 Adobe
...
1 Documents and Settings 1 Temp
1 Windows 2 addins ...
2 Help 3 Tours ...
4 WindowsMediaPlayer 5 Audio
6 Wav ...
5 Img 6 Btn
Subindo...
Subindo...
SQL> set heading off SQL> set linesize 1000 SQL> set pagesize 0
SQL> column nome format a355
1 WMarks 2 Img
3 WindowsMediaPlayer 4 Tours
5 Help 6 Windows
Consultas Hierárquicas Consultas Hierárquicas
A partir do Oracle 9 são suportados joins em consultas hierárquicas
Também passa a ser suportada a ordenação dos nós-filho pela clásula:
ORDER SIBLINGS BY colunas
Bem como o retorno da informação hierárquica concatenada
SYS_CONNECT_BY_PATH(coluna, separador)
Exemplo Exemplo
select sys_connect_by_path(nome,'\') nome from diretorios
start with num_diretorio_pai is null connect by num_diretorio_pai = prior
num_diretorio
order siblings by nome;
Exemplo Exemplo
\Arquivos de programas
\Arquivos de programas\Adobe ...
\Arquivos de programas\Oracle
\Documents and Settings
\Temp
\Windows
\Windows\addins ...
\Windows\Help
\Windows\Help\Tours
\Windows\Help\Tours\htmlTour
\Windows\Help\Tours\mmTour
\Windows\Help\Tours\WindowsMediaPlayer
\Windows\Help\Tours\WindowsMediaPlayer\Audio