Cursor Dinamico no Forms

Dicas do Oracle Forms Builder - Blocos, Itens, LOV, Canvas, Triggers, comandos, PLL, d2kwutil, FMB, Alert, menus, etc
Responder
Zida
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 53
Registrado em: Ter, 08 Jun 2004 2:59 pm
Localização: Toledo - PR

Boa tarde, gostaria de saber se é possível ou se alguém sabe como fazer um cursor dinamico, com a clausua where dinamica no forms.
Tenho visto algo sobre isso, mas apenas encontrei para procedimentos de banco.
Obrigado
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Oi Zida

Temos um exemplo de cursor dinâmico nessa procedure:
http://glufke.net/oracle/viewtopic.php?t=31

Mas será realmente necessário fazer um dinâmico?
Veja como é fácil fazer uma "Where" dinamica SEM usar cursores dinamicos:

Selecionar tudo

select *
from sua_tabela
where 
  (:bloco.mostra_excluidos='S'
   or
   :bloco.mostra_excluidos='N' and  exclusao is null)   
  )
Explicação do WHERE acima:

* Caso o item mostra_excluidos (que é um check-box no meu formulário) estiver S, então o where não filtra nada. Ou seja, mostra tudo, inclusive os excluídos.

* Caso o item mostra_excluidos estiver N, ele filtra mostrando apenas os que não tem data de exclusao. ( exclusao is null )
Editado pela última vez por dr_gori em Sex, 23 Jul 2004 10:54 am, em um total de 1 vez.
Zida
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 53
Registrado em: Ter, 08 Jun 2004 2:59 pm
Localização: Toledo - PR

Intao, este exemplo que me passou, funciona apenas como funcao/procedimento de banco, realmente atenderia nossa necessidade se usassemos como procedure onde pudesse ser retornado mais de uma variavel, mas eu gostaria de usar no proprio FORMS, pois, se para cada cursor que fizessemos tivessemos que criar uma funcao no banco para retornar iria ficar muito dificil de manter os programas atualizados nos clientes, tendo sempre que mandar o programa e as funcoes de seus respectivos cursores que são suas dependencias.
Por exemplo, hoje usamos assim:
Hoje criamos record_groups para este caso, mas para maquinas menores e links de internet não tão bons isso fica muito pesado.
Um exemplo do que gostaria é o seguinte:
Declaramos um curso

Selecionar tudo

CURSOR CUR_ITEM IS
   SELECT DS_ITEM FROM ITEMSIMILAR;
e depois chamamos com

Selecionar tudo

FOR CUR_ITEM LOOP
   comandos...
END LOOP;
Mas por exemplo, gostariamos de carregar apenas a descricao de alguns itens, que o usuario seleciona em tela.
Digamos que o usuario selecionou o item 1,2 e 3 ..
então, nós concatenamos dessa maneira

Selecionar tudo

CL_ITEM := '1,2,3';
gostari de saber se existe alguma forma de usar o cursor passando esses codigos como parametro ..
quando passamos assim:

Selecionar tudo

CURSOR CUR_ITEM IS
   SELECT DS_ITEM 
     FROM ITEMSIMILAR
    WHERE CD_ITEM IN (CL_ITEM);
aparece um erro de numero invalido.

gostariamos de fazer pelo menos o where dinamico como é possivel fazer em records_groups, concatenando strings usando essas declaracoes etc... sera que é possivel ?
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Bem... existe uma forma de você fazer isso sem ter que usar cursores dinâmicos. (Teoricamente, cursores dinâmicos devem ser **sempre** evitados, pois geram parse desnecessário)...

O que você pode criar é uma GTT (Global Temporary Table). você cria uma de apenas um campo, e nesse campo, insere todos os valoes possíveis que você deseja (1, 2, 3 etc...)

Depois disso, você simplesmente filtra por esse campo! Com isso, sua aplicação vai fazer uso dos índices necessários e não vai gerar um Parse cada vez. LEMBRANDO que uma GTT só é vista pela própria sessao. Depois de comitada, tudo some. É algo extremamente rápido. Será que não é por esse lado?
Zida
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 53
Registrado em: Ter, 08 Jun 2004 2:59 pm
Localização: Toledo - PR

A gente já usa essas tabelas, mas houve alguns problemas com elas, em que as vezes o select não retornava dados, ou ficavam muito lentas, tanto em subqueries quando em se colocando as tabelas no proprio from.
Quando tivemos conhecimento dessas tabelas, comecamos a usar de modo "continuo", e grande parte de relatorios apresentou problema, por isso ficamos meio desmotivados e desconfiados de sua usabilidade.
O modo que implementamos ela é o assim:

Selecionar tudo

CREATE GLOBAL TEMPORARY TABLE ITEMAFIXAR_TMP (CD_ITEM NUMBER(7) NOT NULL) ON COMMIT PRESERVE ROWS e criamos um indice para ela:
CREATE INDEX IDX_ITEMAFIXAR_TMP ON ITEMAFIXAR_TMP (CD_ITEM),
você poderia me passar algum exemplo de como você implementa, se você encontrou dificuldades ou problemas em usa-las ?

obrigado e abracos
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Poxa... nunca vi alguém ter problemas com Global Temporary tables. Aqui elas sempre funcionaram muito bem - muito rápidas, por sinal. O que nós náo fizemos aqui foi criar um índice pra ela. (Creio que no seu caso, também não seja necessário, afinal, se você está usando uma GTT apenas pra substituir um WHERE dinamico para filtrar dados, isso significa que são poucos valores... Acho que índice só está atrapalhando nesse caso.)

O motivo de ter dado problema aí, eu não saberia te dizer mesmo... Talvez um DBA tenha a explicação pra isso...
Zida
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 53
Registrado em: Ter, 08 Jun 2004 2:59 pm
Localização: Toledo - PR

Muito obrigado pela ajuda, vamos fazer alguns testes mais aprofundados sobre os indices nessa tabelas, e vamos tentar localizar mais material para estudo sobre isso ...

Obrigado pela ajuda. :)
Avatar do usuário
leobbg
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 29 Out 2004 10:25 am
Localização: PORTO ALEGRE - RS
Leo BBG Consultor Oracle

utilizo essas duas maneiras.. anota ai!

Selecionar tudo

procedure valida is
   --
  vgroup_id      recordgroup;
  vretorno_group number;
	--
begin
	--
  vgroup_id := create_group_from_query( 'RECORD_GROUP', 'select variacao        A ' ||
                                                        ',      data_remarcacao B ' ||
                                                        'from   t_prc_preço_regiao' );
  vretorno_group := populate_group( vgroup_id );
  --
  for i in 1..get_group_row_count( vgroup_id )
  loop
  	--
  	:parametro.numero := get_group_number_cell( 'RECORD_GROUP.A', i );
  	:parametro.data   := get_group_date_cell( 'RECORD_GROUP.B', i );
  	--
  	next_record;
  	
  end loop; 
  --
  first_record;
  --
end;
e a segunda...

Selecionar tudo

procedure sql_dinamico is
  --
  vquery   long := 'select to_char( data_remarcacao, '''DD/MM/YYYY''' ) ' ||
                   ',      variacao                                     ' ||
                   'from t_prc_preço_regiao';
  --
  vcursor  integer;
  vexecute integer;
  vname    varchar2(100);
  --		
begin
  --
  vcursor := dbms_sql.open_cursor;
  dbms_sql.parse( vcursor, vquery, 0 );	
  --
  vexecute := dbms_sql.execute( vcursor );
  --
  dbms_sql.define_column( vcursor, 1, vname, 10000 );
  --
  loop
    --
    if dbms_sql.fetch_rows( vcursor ) = 0 then
      --
  	exit;
  	--
    end if;
    --
    dbms_sql.column_value( vcursor, 1, vname );
    --
  end loop;
  --
end;
falou
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 11 visitantes