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:
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;
/
3. No Botão que chama o relatório, responsável pela chamada do Reports, criar o seguinte código:
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;
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:
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
Dúvidas
r.nevesbraga@gmail.com