quarta-feira, 7 de abril de 2010

Recuperando erro inesperado no Oracle Data Integrator (ODI)

Depois de muito tempo sem postar, estamos aqui novamente, o motivo foi excesso de trabalho (rsrsrsrsrs)

Hoje o Post é de bastante utilidade no desenvolvimento de Integrações, tanto simples quanto complexa.

No desenvolvimento padrão de um ODI, utilizamos vários procedimentos, variáveis e interfaces, porém na execução dos mesmos, poderão ocorrer erros que não estavam previstos e assim fica bastante complicado localizar ou mesmo saber qual foi a origem do erro.
Nesse caso o indicadio criar um procedimento genérico que todos os procedimentos, interfaces ou variáveis apontem o "KO" para ele, assim todo o erro não previsto vai redirecionar para ele com o seguinte código abaixo, você conseguirá exibi-lo:

%=odiRef.getPrevStepLog("MESSAGE")%

Esse comando pode ser utilizado da maneira que você achar mais fácil e que atenda sua necessidade.

Até a próxima...

quinta-feira, 10 de setembro de 2009

Criando um Criteria Dinâmico para o objeto LOV - (OAF).

Nesse Exemplo vamos fazer um passo-a-passo de como criar uma Lov dinâmica, recebendo um ou mais parâmentros.

Vamos pensar no seguinte cenário:

Temos um Página onde a mesma tem um FormValue ou qualquer outro campo que tenha uma valor, e esse valor desse campo vai servir como critério para o resultado de uma Lov.

A primeira coisa a ser feita é montarmos o View Object da Lov, não esquecendo de colocar um campo Transient com o mesmo formato do campo que vai servir de Criteria. Lembrando também que esse atributo no VO tem que ser marcado como Passivate.

Depois crie a Região de Lov adicionando uma Table associada ao VO, na mesma crie um FormValue com o atributo Passivate do VO, pois o mesmo vai receber o valor que estava na Página.

Feito isso, crie um Controller na Table da Lov, e adicione o seguinte código no ProcessRequest:

Dictionary passiveCriteria = (Dictionary)pageContext.getLovCriteriaItems();
//Cria um Dictionary, em seguida pega o valor que vem do LovMap da página requisitante
String passiveInvoiceId = (String)passiveCriteria.get("NomeLovMap");

//Instância o Application Module
OAApplicationModule am = (OAApplicationModule)pageContext.getApplicationModule(webBean);
//Chama o método do AM passando o valor que recebemos do LovMap
am.invokeMethod("execQuery", new Serializable []{passiveInvoiceId});

//Executa a Table para trazer todos os registros
if (!pageContext.isFormSubmission()) {
OATableBean table = (OATableBean) webBean;
table.queryData(pageContext);
}

No Application Module criamos um método que executa uma query dinâmica conforme a sua necessidade.

O último passo é na página que chama a Lov, criarmos o LovMap que refere-se ao valor que vamos passar como critério. No mesmo colocamos no "LOV Region Item" o campo que vai receber, no "Criteria Item" passamos o valor da página que vai servir comom critério, e por último marcamos "Programmatic Query" como "True".

Assim conseguimos montar a nossa Lov dinâmicamente conforme a necessidade do negócio.

Abraços e até a próxima.

quarta-feira, 2 de setembro de 2009

[PL/SQL] Esqueça tabelas temporárias: use funções PIPELINED!

Oi Pessoal,

Por várias vezes temos situações de relatórios, por exemplo, em que a consulta ficaria tão complexa que decidimos gerar uma tabela temporária para basear o relatório, ficando o preenchimento das informações a cargo de uma package PL/SQL que é chamada momentos antes do relatório. No entanto, o Oracle 9i em diante nos permite o uso de funções PIPELINED para atingir o mesmo fim, sem ter que criar tabela nenhuma, e sem necessitar controle sobre a transação (commit, usuários concorrentes etc).

Para fazê-lo, os quatro simples passos são:

1) Criar um type no banco do tipo OBJECT que contenha todos os campos necessários na sua query:
create or replace type test_rec as object (key number, value1 varchar2(100), value2 varchar2(200));

2) Criar um outro type, desta vez como uma tabela do type criado anteriormente:
create or replace type tab_rec as table of test_rec;

3) Criar uma função/package a ser chamada do relatório, com o modificador PIPELINED:
 create or replace function get_test(p_key IN NUMBER) return tab_rec pipelined is
begin
for i in 1..p_key LOOP
pipe row( test_rec(i, 'Test'||i, 'This is test number '||i||' for pipelined functions' ));
end loop;
return;
end;


4) Pronto! Agora é só selecionar os registros direto da função, assim:

SELECT *
FROM TABLE(get_test(2));

KEY VALUE1 VALUE2
----------- -------------- ---------------
1 Test1 This is test number 1 for pipelined functions
2 Test2 This is test number 2 for pipelined functions


Abraços pessoal, até a próxima!

terça-feira, 11 de agosto de 2009

[SQL] Como pegar o último valor não-nulo para preencher colunas

Olá pessoal!

Dica rápida interessante de SQL: Imaginem a seguinte situação, que pode acontecer em queries que possuem outer join por exemplo (usarei uma tabela apenas para simplificar o exemplo):

SELECT empregado, gestor FROM empregados

Empregado Gestor
---------- ----------
Joao Luis
Joao NULL
Roberto Joao
Roberto NULL

Essa query trouxe valores duplicados, uma delas com gestor e outra sem. Agora imagine que queremos copiar o valor GESTOR para os valores onde for nulo, agrupando por EMPREGADO. Para isso, podemos usar a função analítica LAST_VALUE, que traz o último valor de uma série, em conjunto com o modificador IGNORE NULLS para ignorar os valores nulos e particionando pela coluna EMPREGADO (que é não-nula):

SELECT empregado, LAST_VALUE(gestor IGNORE NULLS) OVER (ORDER BY empregado) FROM empregados

Empregado Gestor
---------- ----------
Joao Luis
Joao Luis
Roberto Joao
Roberto Joao

Espero que seja útil para livrá-los de enrascadas! Até mais!

sábado, 1 de agosto de 2009

Chamando Metódo com vários parâmetros através de um click em uma Imagem.

Depois de muito tempo sem postar, estamos aqui novamente.

Hoje vamos mostrar como é feito o seguinte cenário:
Imaginem uma tela principal, onde a mesma contém uma Tabela com diversas colunas, e uma das colunas é um campo Imagem, onde eu tenha que chamar algum evento através de um click como a imagem abaixo.




O primeiro passo é colocarmos uma coluna em nossa Table ou AdvancedTable, com um objeto Image. No mesmo adicionar na propriedade Image URL o nome da imagem.
Obs. Segue o link onde contém todas as imagens e seus nomes que existem no servidor o Oracle EBS: http://www.oracle.com/technology/tech/blaf/specs/iconList.html

Em seguida, vamos alterar a propriedade da imagem "Action Type" para fireAction, e altere o atributo Event para um texto mais familiar ao evento. Para passar parâmetros que estão no View Object da nossa tabela, vá na propriedade da imagem "Parameters" e clique no mesmo, abrirá uma form como a imagem abaixo:



Assim podemos passar quantos parâmetros necessitarmo, lembrando que o "Name" é o nome que vamos pegar no Controller, e o "Value" é o ${oa..}.

Para recuperarmos os mesmos dentro do Controller e passarmos para o nosso Appication Module, é bastante simples.

No processFormRequest do controller da página colocamos o seguinte código:



Assim quando clicarmos na imagem ela irá passar os parâmetros do VO, onde pegaremos no Controller e repassaremos para nosso Appication Module, assim podendo fazer as ações que desejarmos como Alterar, Excluir, Processar, Chamar Concurrent e etc...

Um grande abraço e até a próxima.