[TUTORIAL] - REPORTS BASEADO EM RECORD GROUP

Coloque aqui tutoriais (por enquanto, sobre qualquer assunto relacionado a Oracle) e apostilas.
Responder
ricards
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 52
Registrado em: Sáb, 29 Set 2007 12:59 am
Localização: Araraquara-SP
Contato:
Ricardo Neves
Analista e Instrutor Oracle Developer
Java Developer (JPA/JSF/Hibernate/WebServices/EJB)

REPORTS BASEADO EM RECORD GROUP

Na criação de um REPORT baseado em Record Group os dados estarão armazenados em “TYPES” (Registros) em procedures na base de dados.
Vantagens de criar um REPORT baseado em Record Group:
• Relatórios que possuem grandes quantidades de informações.
• As informações são recuperadas em uma procedure, sendo necessário dar permissões apenas para esta procedure e não para as tabelas envolvidas.
• Rapidez no processamento das informações, pois o processo está sendo carregado na base de dados.
• Legibilidade de código.
• Fácil manutenção.
• Ganho em performance.
• Redução de Código na aplicação visual.

A seguir será apresentado o passo a passo para a construção de um Report baseado em Record Group.

1. Criar uma package que possua os TYPES e PROCEDURES que retornarão as informações para o relatório:

Selecionar tudo


create	or	replace	package	pkg_treinamento	is
	-- Registro de empregados
	type	v_rec_produtos	is	record	(
							cd_produto	       number,
							nm_produto	       varchar2(500),
                                                        vl_compra              number,
                                                        vl_venda               number,
                                                        qt_produto             number,
                                                        dt_atualizacao         date,
                                                        nm_usuario_atualizacao varchar2(50)      
						);
	type	v_tab_produtos	is	table	of	v_rec_produtos	index	by	binary_integer;
	-- Procedure responsavel por retorna os empregados em um registro
	procedure	prc_carrega_produtos	(
							p_tab_produtos   	in	out	v_tab_produtos,
							p_mens			in	out	varchar2
						);
end	pkg_treinamento;
/
create	or	replace	package	body	pkg_treinamento	is
	-- Procedure responsavel por carregar os produtos em um registro
	procedure	prc_carrega_produtos	(
							p_tab_produtos   	in	out	v_tab_produtos,
							p_mens			in	out	varchar2
						)       is
                -- Cursor que recupera todos os produtos da base
		cursor	c1	is
                        select  p.cd_produto,
                                p.nm_produto,
                                p.vl_compra,
                                p.vl_venda,
                                p.qt_produto,
                                p.dt_atualizacao,
                                p.nm_usuario_atualizacao
                        from    tb_produtos     p;

		v_ind		number	:=	0;
	begin
		-- Carrega o registro de produtos
		for	r1	in	c1	loop
			v_ind	:=	v_ind	+	1;
			p_tab_produtos(v_ind).cd_produto	        :=	r1.cd_produto;
			p_tab_produtos(v_ind).nm_produto	        :=	r1.nm_produto; 
                        p_tab_produtos(v_ind).vl_compra	                :=	r1.vl_compra; 
                        p_tab_produtos(v_ind).vl_venda	                :=	r1.vl_venda;
                        p_tab_produtos(v_ind).qt_produto	        :=	r1.qt_produto;
                        p_tab_produtos(v_ind).dt_atualizacao	        :=	r1.dt_atualizacao;
                        p_tab_produtos(v_ind).nm_usuario_atualizacao	:=	r1.nm_usuario_atualizacao; 
		end	loop;
	exception
		when	others	then
			p_mens	:=	'PKG_TREINAMENTO.PRC_CARREGA_PRODUTOS - Problemas ao executar a rotina. Erro: '	||	sqlerrm;
	end;
end	pkg_treinamento;
/

2. Criar um Forms que será responsável pela passagem de parâmetros para o relatório.
3. No Botão que chama o relatório, responsável pela chamada do Reports, criar o seguinte código:

Selecionar tudo


DECLARE
    -- LISTA DE PARÂMETROS E RECORD GROUPS  
    LISTA_PARAMETROS            		 PARAMLIST;
		RG_GRUPO_PRODUTO		             RECORDGROUP;
		-- COLUNAS DO RECORD GROUP DE PRODUTOS
    CD_PRODUTO                       GROUPCOLUMN; --NUMBER  
    NM_PRODUTO                       GROUPCOLUMN; --VARCHAR2(500)  
    VL_COMPRA                     	 GROUPCOLUMN; --NUMBER
    VL_VENDA                         GROUPCOLUMN; --NUMBER
    QT_PRODUTO                       GROUPCOLUMN; --NUMBER
    DT_ATUALIZACAO                   GROUPCOLUMN; --DATE
    NM_USUARIO_ATUALIZACAO					 GROUPCOLUMN; --VARCHAR2(50)  
    -- CRIAR UMA VARIÁVEL DO TIPO V_TAB_PRODUTOS (TYPE)
    V_TAB_PRODUTOS									 PKG_TREINAMENTO.V_TAB_PRODUTOS;
    V_MENS													 VARCHAR2(300)	:=	NULL;
BEGIN
		-- VERIFICA SE EXISTE UM RECORD GROUP PRODUTO JÁ CRIADO	
		RG_GRUPO_PRODUTO	:= FIND_GROUP('PRODUTO');
		-- SE EXISTIR EXCLUI O RECORD GROUP
  	IF NOT ID_NULL(RG_GRUPO_PRODUTO) THEN
 	   	DELETE_GROUP(RG_GRUPO_PRODUTO);
  	END IF;
  	-- CRIA UM RECORD GROUP PRODUTO
    RG_GRUPO_PRODUTO 	   	     :=	CREATE_GROUP('PRODUTO', GLOBAL_SCOPE);
  	-- CRIA AS COLUNAS DO RECORD GROUP PRODUTO SEMPRE COM O MESMO NOME DAS COLUNAS DO TYPE
  	CD_PRODUTO                 := ADD_GROUP_COLUMN(RG_GRUPO_PRODUTO, 'CD_PRODUTO'                ,  NUMBER_COLUMN  , 10 );
  	NM_PRODUTO                 := ADD_GROUP_COLUMN(RG_GRUPO_PRODUTO, 'NM_PRODUTO'                ,  CHAR_COLUMN    , 500);
  	VL_COMPRA                  := ADD_GROUP_COLUMN(RG_GRUPO_PRODUTO, 'VL_COMPRA'            		 ,  NUMBER_COLUMN  , 20 );
		VL_VENDA              		 := ADD_GROUP_COLUMN(RG_GRUPO_PRODUTO, 'VL_VENDA'               	 ,  NUMBER_COLUMN  , 20 );	
		QT_PRODUTO                 := ADD_GROUP_COLUMN(RG_GRUPO_PRODUTO, 'QT_PRODUTO'                ,  NUMBER_COLUMN  , 10 );
		DT_ATUALIZACAO             := ADD_GROUP_COLUMN(RG_GRUPO_PRODUTO, 'DT_ATUALIZACAO'            ,  DATE_COLUMN    , 20 );
		NM_USUARIO_ATUALIZACAO     := ADD_GROUP_COLUMN(RG_GRUPO_PRODUTO, 'NM_USUARIO_ATUALIZACAO'    ,  CHAR_COLUMN    , 50 );
		-- CARREGA AS INFORMAÇÕES DA PROCEDURE PARA O RECORD GROUP
    PKG_TREINAMENTO.PRC_CARREGA_PRODUTOS	(
    																				P_TAB_PRODUTOS	=>	V_TAB_PRODUTOS,
    																				P_MENS					=>	V_MENS	
    																			);
    -- CASO DER ERRO NA PRODCEDURE EXIBE A MENSAGEM
    IF	V_MENS	IS	NOT	NULL	THEN
    		MESSAGE(V_MENS);
    		MESSAGE(V_MENS);
    		RAISE	FORM_TRIGGER_FAILURE;
    END	IF;
    -- LE O TYPE DE PRODUTOS
    FOR V_IND IN NVL(V_TAB_PRODUTOS.FIRST,1) .. NVL(V_TAB_PRODUTOS.LAST,0) LOOP
    	  -- A CADA ITERAÇÃO ADICIONA UMA LINHA NO RECORD GROUPO DE PRODUTOS
				ADD_GROUP_ROW        (RG_GRUPO_PRODUTO      , V_IND);
        -- ADICIONA AS COLUNAS NA LINHA CRIADA CONFORME O TIPO DE DADOS
				SET_GROUP_NUMBER_CELL(CD_PRODUTO               , V_IND,	V_TAB_PRODUTOS(V_IND).CD_PRODUTO                     );		
				SET_GROUP_CHAR_CELL  (NM_PRODUTO               , V_IND,	V_TAB_PRODUTOS(V_IND).NM_PRODUTO                     );
				SET_GROUP_NUMBER_CELL(VL_COMPRA                , V_IND,	V_TAB_PRODUTOS(V_IND).VL_COMPRA                      );
				SET_GROUP_NUMBER_CELL(VL_VENDA                 , V_IND,	V_TAB_PRODUTOS(V_IND).VL_VENDA                       );
				SET_GROUP_NUMBER_CELL(QT_PRODUTO               , V_IND,	V_TAB_PRODUTOS(V_IND).QT_PRODUTO                     );
				SET_GROUP_DATE_CELL  (DT_ATUALIZACAO           , V_IND,	V_TAB_PRODUTOS(V_IND).DT_ATUALIZACAO                 );		
				SET_GROUP_CHAR_CELL  (NM_USUARIO_ATUALIZACAO   , V_IND,	V_TAB_PRODUTOS(V_IND).NM_USUARIO_ATUALIZACAO         );
				--
    END LOOP;
    -- CRIAR LISTA DE PARAMETROS PARA O REPORT
    LISTA_PARAMETROS := GET_PARAMETER_LIST('TMPDATA');
    --
    IF NOT ID_NULL(LISTA_PARAMETROS) THEN
        DESTROY_PARAMETER_LIST(LISTA_PARAMETROS);
    END IF;	
    --
    LISTA_PARAMETROS := CREATE_PARAMETER_LIST('TMPDATA');
    --
    ADD_PARAMETER(LISTA_PARAMETROS, 'PARAMFORM' , TEXT_PARAMETER, 'NO');       
    -- REFERENCIA O RECORD GROUP PRODUTO A Q_1 - QUERY DO REPORT	         
		ADD_PARAMETER(LISTA_PARAMETROS, 'Q_1'         , DATA_PARAMETER, 'PRODUTO');
		-- CHAMA O RELATORIO
		RUN_PRODUCT(REPORTS, 'C:\Documents and Settings\Administrador\Desktop\RELATORIO.REP', SYNCHRONOUS, RUNTIME, FILESYSTEM, LISTA_PARAMETROS, NULL);
		--
		DESTROY_PARAMETER_LIST(LISTA_PARAMETROS);
		--    
EXCEPTION
		WHEN	FORM_TRIGGER_FAILURE	THEN
					RAISE;    	
		WHEN	OTHERS THEN
		    	MESSAGE('Erro ao gerar o relatório. Erro: ' || SQLERRM);
		    	MESSAGE('Erro ao gerar o relatório. Erro: ' || SQLERRM);
		    	RAISE FORM_TRIGGER_FAILURE;    	
END;

4. No reports criar uma query atentando-se com o nome das colunas, que devem ser identicas ao nome, tipo e tamanho das colunas do type.
5. O nome da query também deve ser o mesmo do utilizado no forms. (Q_1).
6. Na query do reports deve ser feito um SELECT na tabela DUAL conforme as regras abaixo:
• Para colunas do tipo CHAR, VARCHAR, VARCHAR2 devem ser colocados ESPAÇOS OU LETRAS conforme o tamanho da coluna. Ex: VARCHAR2(5)
select ‘ ’ <COLUNA_TYPE> from dual
ou
select ‘AAAAA’ <COLUNA_TYPE> from dual
• Para colunas do tipo NUMBER devem ser colocado o número 0.
select 0 <COLUNA_TYPE> from dual
• Para colunas do tipo DATE devem ser colocada a instrução SYSDATE.
select SYSDATE <COLUNA_TYPE> from dual

7. A query do relatório fica da seguinte forma:

Selecionar tudo


SELECT	0		CD_PRODUTO,
	'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'	NM_PRODUTO,
	0		VL_VENDA,
	0		VL_COMPRA,
	0		QT_PRODUTO,
	SYSDATE	DT_ATUALIZACAO,
	'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'	NM_USUARIO_ATUALIZACAO
FROM 	DUAL

8. Pronto agora é só fazer os devidos ajustes no Report como de costume (Quebras, Fórmulás, etc.).

Dúvidas

r.nevesbraga@gmail.com
Diego_Mello
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 229
Registrado em: Sex, 05 Set 2008 2:59 pm
Localização: Igrejinha - RS
Diego Mello
Igrejinha - RS
www.twitter.com/diegolmello

Fala, ricards! Blza?
Cara, só uma dica... a mais! :P

Ao invés de usar:

Selecionar tudo

select ‘AAAAA’ <COLUNA_TYPE> from dual 
Use:

Selecionar tudo

SELECT RPAD(' ', 5) < coluna_type >
  FROM dual
Mais fácil de entender caso tenha um campo de muitos caracteres. :D
Renan Orati
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 90
Registrado em: Qui, 23 Ago 2007 3:40 pm
Localização: São José do Rio Preto - SP

Bom dia a todos,

É possivel usar a passagem de RECORD_GROUP para o REPORTS na versão 10g?!
Estou tentando e está retornando o seguinte erro:
REP-53053: Argumentos inválidos para a chamada de função
Vlw!
Responder
  • Informação
  • Quem está online

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