- Este tópico contém 6 respostas, 3 vozes e foi atualizado pela última vez 15 anos atrás por fsitja.
-
AutorPosts
-
22 de outubro de 2009 às 7:47 pm #90371rwarstatParticipante
Pessoal,
Estou começando a trabalhar com arrays, e estou com um erro que não consegui resolver ainda.Fiz o código abaixo para que carregasse os dados de um cursor em um dado do tipo tabela e depois pudesse trabalhar com ela, ao invés do cursor. De acordo com o que li, isso eliminaria a troca de contexto entre SQL e PL/SQL, aumentando assim a performance do programa.
O problema é que quando vou fazer o count na v_hosp me retorna que a tabela não existe. Alguém sabe o quê estou fazendo de errado?
DECLARE
TYPE rec_hosp IS RECORD (
cd_hospital hospital.cd_hospital%TYPE,
sc_hospital hospital.sc_hospital%TYPE
);TYPE tb_hosp IS TABLE OF rec_hosp
INDEX BY BINARY_INTEGER;v_hosp tb_hosp;
qtde NUMBER;CURSOR cur_hosp
IS
SELECT cd_hospital, sc_hospital
FROM hospital;
BEGIN
OPEN cur_hosp;LOOP
EXIT WHEN cur_hosp%NOTFOUND;FETCH cur_hosp
BULK COLLECT INTO v_hosp;
END LOOP;CLOSE cur_hosp;
SELECT COUNT (cd_hospital)
INTO qtde
FROM v_hosp;DBMS_OUTPUT.put_line (qtde);
END;Abraço,
Roberto22 de outubro de 2009 às 9:31 pm #90381diegolenhardtParticipanteTenta assim…
dbms_output.put_line(v_hosp.count);
22 de outubro de 2009 às 9:43 pm #90382rwarstatParticipanteAssim funcinou.
Isso quer dizer que não posso fazer um select em v_hosp?23 de outubro de 2009 às 1:01 am #90401diegolenhardtParticipanteNão pode fazer select na variavel, pode acessar assim
vCdHospital := v_hosp(1).cd_hospital;
vai retornar o cdHospital da posição 1 para variavel vCdHospital,
qualquer coisa manda aí
23 de outubro de 2009 às 5:42 pm #90424rwarstatParticipanteA minha dúvida é a seguinte, como é que posso transformar o código abaixo para diminuir a troca de contexto?
BEGIN
FOR cur_pac IN (SELECT cd_paciente, nm_paciente
FROM paciente
WHERE nm_paciente LIKE 'A%')
LOOP
DBMS_OUTPUT.put_line (cur_pac.cd_paciente || ' - ' || cur_pac.nm_paciente);
END LOOP;
END;Tenho uma package onde preciso utilizar vários cursores, sendo muitos com selects com joins entre várias tabelas e com unions. Na teoria, se utilizasse “bulk collect” eu conseguiria reduzir a troca de contexto e com isso aumentar a performance da package. Mas ainda não consegui transformar um desses cursores para utilizar “bulk collect”.
Roberto
23 de outubro de 2009 às 7:50 pm #90429rwarstatParticipanteFormulando melhor a questão, como faço para usar arrays ao invés de cursores e consequentemente aumentar a performance do meu programa quando preciso trabalhar somente com algumas colunas de uma tabela, ou com colunas de várias tabelas?
Um exemplo que tenho é um cursor que tenho em que o select traz campos de 7 tabelas distintas.
Obrigado,
Roberto27 de outubro de 2009 às 8:09 pm #90516fsitjaParticipanteÉ pelo que caminho que você estava indo. Declarando um type que contenha os campos que você precisa e outro type que seja um table do type anterior.
Seu bulk collect deve conter uma cláusula de LIMIT. Senão o que pode acontecer se sua tabela tiver milhares (ou milhões) de linhas? Você vai consumir toda a memória do seu servidor com uma collection gigantesca.
Um LIMIT razoável é de 100 registros por vez, fazendo 2 loops aninhados:
um deles faz o fetch com bulk collect e o outro dentro percorre os registros com um for de 1 até “sua_tabela.count”, fazendo o processamento que você precisar.Tem vários exemplos na documentação oracle, usando object types. Mas dá para fazer com table de records também.
Só um parêntese, se você usar nested table, dá para fazer um select no estilo:
select col1, col2, col3
from table(minha_tab_array)
Só lembre que há chaveamento de contexto e tudo mais, mas é razoável pela flexibilidade que oferece.
O link abaixo tem bastante sobre o que você procura:
http://download.oracle.com/docs/cd/E118 … osites.htm -
AutorPosts
- Você deve fazer login para responder a este tópico.