sexta-feira, 15 de março de 2013

Como submeter, aguardar e verificar o status dos Concorrentes via Código

Olá!

Hoje vamos falar um pouco de Oracle Concurrents. Os Concurrents, também chamados de Concorrentes, por nós Brazucas, são transações específicas dentro Oracle EBS (Oracle E-Business Suite, popularmente chamado de Application), com o objetivo de executar determinadas tarefas de forma organizada e lógica. Eles podem obedecer a uma hierarquia e a uma sequência de execução. Os concorrentes são cadastrados como programas dentro do EBS, onde é possível, inclusive, definir uma série de parametrizações e formas de execução. Eles também podem ser agrupados para execução em conjunto, inclusive interagindo-se entre si. As execuções são realizadas por uma tela de gerenciamento de execução, onde de lá, chamamos determinado concorrente cadastrado e submetemos o mesmo à execução. Através desta tela, podemos acompanhar o status de execução e algumas informações como saídas e logs de erro. Também podemos executar um concorrente através de uma opção de menu, o que é comum em alguns casos. Contudo, o foco deste post não é entrar em detalhes sobre como são cadastrados e definidos os concorrentes dentro do EBS. Para isto sugiro consultar a documentação do Oracle E-Business Suite. O foco aqui é demonstrar como executar um concorrente via código, de dentro de uma PROCEDURE, PACKAGE ou FORMS, por exemplo. Apenas para constatar, além dos objetos de banco de dados, também podemos executar concorrentes através de Forms, Reports ou arquivos externos, como por exemplo, arquivos com extensão SQL.

Abaixo segue o pacote para a execução de um concorrente. Conforme, falei, precisamos definir algumas informações e parametrizações para que a execução possa ser realizada com sucesso.

w_request_id := fnd_request.submit_request( application IN varchar2
                                           ,program     IN varchar2
                                           ,description IN varchar2 default NULL
                                           ,start_time  IN varchar2 default NULL
                                           ,sub_request IN boolean  default FALSE
                                           ,argument1   IN varchar2 default CHR(0)
                                           ...
                                           ,argumentNN  IN varchar2 default CHR(0));

Conforme pode ser visto a cima, o pacote é o FND_REQUEST e a função é a SUBMIT_REQUEST. Esta função retorna o REQUEST_ID (no exemplo, recebido pela variável W_REQUEST_ID), que é o número da solicitação (ID do concorrente, como nós chamamos). Caso o pedido de execução do concorrente tenha ocorrido com sucesso, a função retornará o ID gerado pela submissão. Caso contrário, ele retornará 0 (zero). Note que este retorno não diz repeito ao status da execução propriamente dita do concorrente, ele é referente a submissão de execução, ou seja, diz respeito ao seu start. Se o Oracle conseguiu iniciar a execução, isto é tido como sucesso, e, portanto, é gerado um ID de solicitação para então prosseguir para a execução.
Além dos parâmetros que podem ser definidos pelo usuário, existem outros que são nativos e requeridos, que devem ser informados para que o start da execução tenha sucesso. São eles:

- Application: Short Name (apelido) da aplicação, por exemplo, AR, PO, SQLAP, etc. Ele vai variar dependendo de qual aplicação origem você deseja executar o concorrente. Por exemplo, se você estiver executando um concorrente do AR e o mesmo estiver configurado para este módulo, é necessário verificar qual é o Short Name do AR. Lembrando, que um concorrente cadastrado no EBS, está ligado a uma aplicação. Este apelido, você pode encontrar no cadastro de aplicações no Oracle EBS, pelas responsabilidades de administração e desenvolvimento do sistema.

- Program: Nome abreviado do concorrente. Quando cadastramos a definição do concorrente, temos que criar um nome abreviado para o mesmo. É este nome que devemos informar neste parâmetro.

- Description: Nome que irá aparecer na janela de solicitações de concorrentes, quando o mesmo for submetido. Caso não seja informado um (o padrão é deixar nulo), ele pegará o nome cadastrado na definição do concorrente. (default NULL)

- Start_time: Indica a hora de início da solicitação. Deixando como nulo caracterizará execução imediata. (default NULL)
- Sub_request: Indica a execução como sendo uma execução filha de outra. (default FALSE)

- Argument1: Primeiro parâmetro da execução. Se o concorrente contiver parâmetros para execução, é aqui que são informados. (default CHR(0))

- ArgumentNN: Último parâmetro, tipo ARGUMENT, no total de 100, que podemos utilizar. (default CHR(0)

Note que todos os parâmetros são do tipo IN, ou seja, de entrada.


Considerações sobre os parâmetros (Arguments):


Como eles possuem valores padrões em suas definições, os chamados valores Default, não necessitamos informar os 100 parâmetros, caso os mesmos não sejam utilizados. Contudo, levando em conta minha experiência em desenvolvimento, já houve casos de problemas na execução, se estes valores padrões não fossem informados. Desta forma, fica a dica. Caso algum erro esteja acontecendo e tudo já foi verificado, pode ser o momento de testar coisas imagináveis, como por exemplo, esta. Por via das dúvidas, sempre informo ;-p. Veja como ficaria a chamada, informando o todos os parâmetros:

w_request_id := fnd_request.submit_request
( 'INV'
 ,'INV'
 ,null
 ,null
 ,false
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
 ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
); 

No total, a chamada da função totaliza 105 parâmetros.

ATENÇÃO: Outro fator importante que deve ser considerado é que determinados concorrentes, principalmente, os nativos (se diz nativos, aqueles que são padrões do EBS, e não os customizados), podem necessitar de valores de determinadas variáveis de ambiente, ou variáveis locais para funcionar. Desta forma, quando você executa um concorrente nativo via código, através de um objeto customizado, por exemplo, estas variáveis podem não estar visíveis, podendo ocasionar um erro, não permitindo que o concorrente seja submetido. Caso isto aconteça, podemos simular o ambiente do EBS, configurando algumas varáveis.
Para mais detalhes sobre estas configurações, veja o artigo “Simulando sessão Oracle Application em Ferramentas de acesso a Banco de Dados”, neste blog.


Verificando Status do Concorrente:


Dentro do pacote FND_CONCURRENT há funções e procedimentos que podem ser úteis quando estamos manipulando concorrentes, e uma destas utilidades é a verificação do status ou da fase de um concorrente, em um determinado momento da execução, sendo durante ou após término da mesma. Veja a chamada a seguir:

w_request_status := fnd_concurrent.get_request_status( request_id      IN OUT NOCOPY number,
                                              ,appl_shortname  IN varchar2 default NULL,
                                             ,program         IN varchar2 default NULL,
                                             ,phase           OUT NOCOPY varchar2,
                                             ,status          OUT NOCOPY varchar2,
                                             ,dev_phase       OUT NOCOPY varchar2,
                                             ,dev_status      OUT NOCOPY varchar2,
                                             ,message         OUT NOCOPY varchar2);

Esta função, que retorna true ou false, possui parâmetros de saída e de entrada. Veja o significado de cada um deles:

Parâmetros de Entrada (IN):

- Request_id : ID do Concorrente que deve ser verificado. Obs. Este parâmetro também é de saída (OUT).
Obs.: Se a informação referente a aplicação (appl_shortname) e ao programa (Program) é passado como parâmetro, o ID do Concorrente mais recente para este programa é devolvido juntamente com o estado e fase.

- Appl_shortname: É referente a Aplicação o qual o programa pertence.
- Program: É referente ao nome do programa. Os parâmetros Appl_shortname e Program são usados somente se o ID do Concorrente não for fornecido.

Parâmetros de Saída (OUT):

- Phase: Retorna a Fase referente a execução do concorrente, no formato display, como por exemplo, “Em Execução” ou “Concluído” (depende da linguagem).

- Status: Retorna o Status referente a execução do concorrente, no formato display, como por exemplo, “Normal” (depende da linguagem).

- Dev_phase: Retorna a Fase referente a execução do concorrente, no formato código, como por exemplo, “RUNNING” ou “COMPLETE” (utilizado para comparações e verificações universais em programas).

- Dev_status: Retorna o Status referente a execução do concorrente, no formato código, como por exemplo, “NORMAL” (utilizado para comparações e verificações universais em programas).

- Message: Mensagem de conclusão do concorrente. Por exemplo, “Conclusão normal” (depende da linguagem).

Abaixo, um exemplo de chamada:

w_request_status := fnd_concurrent.get_request_status( w_request_id
                                                      ,null
                                                      ,null
                                                      ,v_phase
                                                      ,v_status
                                                      ,v_dev_phase
                                                      ,v_dev_status
                                                      ,v_message);


Aguardando a conclusão...:


Quando um concorre é submetido através de código, o pacote envia a solicitação e libera o objeto que está submetendo, para continuar sua sequencia de execução. Contudo, dependendo da necessidade, pode-se querer esperar o término da execução do concorrente, para que seja possível tomar alguma ação mediante o status da execução. Para isto, podemos utilizar o pacote FND_CONCURRENT.WAIT_FOR_REQUEST. Este pacote faz com que o objeto chamador aguarde pelo término da execução do concorrente. A chamada deste pacote deve ser realizada após a submissão do concorrente, pela chamada SUBMIT_REQUEST e após se certificar que o concorrente foi submetido (através do retorno do ID do concorrente vindo da função). Outro detalhe, a chamada ao WAIT_FOR_REQUEST, deve ser precedida de um COMMIT. Veja o exemplo abaixo:

...
if not fnd_concurrent.wait_for_request(w_request_id, 2, 0, v_phase, v_status, v_dev_phase,    v_dev_status, v_message) then
    raise_application_error(-20001, v_message);
else
  if v_dev_status not in ('NORMAL', 'WARNING')  then
    raise_application_error(-20001, v_message);
  end if;
end if;
...

Note no exemplo acima, que através do parâmetro de retorno V_DEV_STATUS, conseguimos saber com qual status o concorrente finalizou. Lembrando, que a chamada WAIT_FOR_REQUEST só libera a continuação da execução do objeto chamador, após o término da execução do concorrente ou após um tempo que pode ser definido na chamada desta função.

Além dos parâmetros referentes ao Status do concorrente, esta função, que retorna true ou false, também possui outros parâmetros de entrada e saída. Veja o significado de cada um deles:

w_request_wait := wait_for_request( request_id IN number default NULL
                               ,interval   IN number default 60
                               ,max_wait   IN number default 0
                               ,phase      OUT NOCOPY varchar2
                               ,status     OUT NOCOPY varchar2
                               ,dev_phase  OUT NOCOPY varchar2
                               ,dev_status OUT NOCOPY varchar2
                               ,message    OUT NOCOPY varchar2);


Parâmetros de Entrada (IN):

- Request_id: ID do Concorrente que deve ser monitorado, ou seja, esperar a conclusão.

- Interval: Frequência da verificação de término do concorrente (padrão 60 segundos).

- Max_wait: Quantidade máxima de espera (em segundos) para a conclusão do concorrente (coloque 0 para espera infinita).

Parâmetros de Saida (OUT):

- Phase: Retorna a Fase referente a execução do concorrente, no formato display, como por exemplo, “Em Execução” ou “Concluído” (depende da linguagem).

- Status: Retorna o Status referente a execução do concorrente, no formato display, como por exemplo, “Normal” (depende da linguagem).

- Dev_phase: Retorna a Fase referente a execução do concorrente, no formato código, como por exemplo, “RUNNING” ou “COMPLETE” (utilizado para comparações e verificações universais em programas).

- Dev_status: Retorna o Status referente a execução do concorrente, no formato código, como por exemplo, “NORMAL” (utilizado para comparações e verificações universais em programas).

- Message: Mensagem de conclusão do concorrente. Por exemplo, “Conclusão normal” (depende da linguagem).

Segue um exemplo completo, implementando todos estes recursos:


declare
  --
  -- Variável para a chamada SUBMIT_REQUEST.
  w_request_id     integer;
  w_request_status boolean;
  w_nr_verificacao number;
  w_cancel_request boolean;
  --
  -- Variáveis para a chamada WAIT_FOR_REQUEST.
  v_phase       varchar2(20);
  v_status      varchar2(20);
  v_message     varchar2(150);
  v_dev_phase   varchar2(20);
  v_dev_status  varchar2(20);
  --
  -- Variáveis para simulação da sessão EBS.
  w_resp_appl_id varchar2(50);
  w_resp_id      varchar2(50);
  w_user_id      varchar2(50);
  w_org_id       varchar2(50);
  --
begin
  --------------------------------
  --Submete o processo concorrente
  --------------------------------
  w_request_id := fnd_request.submit_request( 'TGR'
                                             ,'TGR_GL_GERA_VIS_ORCATO_FUT_ALL'
                                             ,null
                                             ,null
                                             ,false
                                             ,'371' ,'N' ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                             ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                            );
  --
  -----------------------------------------------------------------------
  -- Verifica se foi submetido com sucesso.
  -- Se foi submetido com sucesso, W_REQUEST_ID terá o ID do concorrente.
  -- Caso contrário, ele terá 0 (zero).
  -----------------------------------------------------------------------
  if w_request_id = 0 then
    raise_application_error(-20001, 'Não foi possível submeter o concorrente !!!: '||w_request_id);
  else
    dbms_output.put_line('Concorrente gerado: '||w_request_id);
  end if;
  --
  commit; -- Sempre colocar quando usar wait_for_request.
  --
  ------------------------------------
  -- Verifica o Status do Concorrente.
  ------------------------------------
  w_request_status := fnd_concurrent.get_request_status( w_request_id
                                                        ,null
                                                        ,null
                                                        ,v_phase
                                                        ,v_status
                                                        ,v_dev_phase
                                                        ,v_dev_status
                                                        ,v_message);
  --
  -- --------------------------------------------------------------
  -- Entra no processo de espera pelo términco do concorrente.
  -- --------------------------------------------------------------
  w_nr_verificacao := 1;
  loop
    --
    ---------------------------------------
    -- Aguarda a conclusão com concorrente.
    ---------------------------------------
    if not fnd_concurrent.wait_for_request( w_request_id
                                           ,1 -- verifica após um 1 segundo (sleep).
                                           ,3 -- após o início da verificação, aguarda 3 segundos e encerra a espera.
                                           ,v_phase
                                           ,v_status
                                           ,v_dev_phase
                                           ,v_dev_status
                                           ,v_message) then
      --
      raise_application_error(-20001, v_message);
      --
    end if;
    --
    -- Após 3 verificações de espera, e o concorrente ainda não finalizou, cancela a execução.
    if w_nr_verificacao = 3 then
      -- ---------------------------------------------------------------------------------------
      -- Se depois de 3 verificações o concorrente ainda não concluiu, cancelamos o concorrente.
      -- ---------------------------------------------------------------------------------------
      w_cancel_request := fnd_concurrent.Cancel_Request( w_request_id
                                                        ,v_message);
      --
      dbms_output.put_line('O tempo de execução inspirou! ('||w_nr_verificacao||' verificações).');
      --
    end if;
    --
    exit when (v_dev_phase = 'COMPLETE');
    --
    w_nr_verificacao := w_nr_verificacao + 1;
    --
  end loop;
  --
  dbms_output.put_line('Mensagem: '||v_message);
  --
  -----------------------------------------
  -- Verifica se foi concluído com sucesso.
  -----------------------------------------
  if v_dev_status not in ('NORMAL', 'WARNING')  then
    dbms_output.put_line('Concorrente terminou com erro: '||v_status);
  else
    dbms_output.put_line('Concorrente terminou com o status: '||v_status);
  end if;
  --
end;


Observações Gerais:

Para que a execução via código funcione, o concorrente deve estar cadastrado no EBS, com seus parâmetros definidos (caso houver), e repeitar a sequência destes parâmetros na chamada SUBMIT_REQUEST, ou seja, no caso da chamada via código, a sequencia dos parâmetros deve ser igual a sequencia cadastrada na definição do concorrente do EBS.

O que deve ficar claro, também, é que os parâmetros definidos no cadastro do concorrente (no EBS) são os equivalentes Argument1 a ArgumentNN da função.

Outro ponto que deve ser observado, é que alguns parâmetros utilizados nas chamadas de funções e procedimentos têm a diretriz NOCOPY. Parâmetros deste tipo não podem receber valores diretamente na chamada. Nestes casos, precisamos declarar variáveis para receber ou enviar valores, e utilizar as mesmas nas chamadas dos objetos.

Falows!

sexta-feira, 8 de março de 2013

Em breve novos posts....

Pessoal,

Ando meio sumido, mas em breve volto com mais posts...

Abraço!

segunda-feira, 4 de março de 2013

E assim nasce mais um blog Oracle

Pessoal, segue mais uma fonte de conhecimento Oracle.
Nosso amigo Eduardo Schurtz, disponibilizou um blog sobre dicas, notícias, produtividade, lifehacking, caça aos bugs e tudo que se refere ao seu dia-a-dia no mundo Oracle EBS. Vale a pena conferir...

Boa sorte, Eduardo! Parabéns pela iniciativa!

http://eduardoschurtz.com/oracle/2013/02/e-assim-nasce-mais-um-blog-oracle/

quarta-feira, 7 de abril de 2010

Retorna registros randômicos entre um grupo de registros

Hi!

Abaixo segue um exemplo bem interessante onde dentro de um grupo de registros é escolhido um registro aleatório.  Note que além da função DBMS_RANDOM, são utilizadas as funções RANK e OVER.
Em nossa tabela exemplo, teremos os seguintes dados:

Tabela: teste_random

Nome    Numero

======  ======
Felipe  1
Felipe  2
Felipe  3
Thiago  1
Thiago  2
Thiago  3
Edna    1

Segue SCRIPT para a criação da tabela e INSERTs:

create table teste_random
( nome   char(6)
 ,numero char(1)
)
/
insert into teste_random
values
('Felipe','1')
/
insert into teste_random
values
('Felipe','2')
/
insert into teste_random
values
('Felipe','3')
/
insert into teste_random
values
('Thiago','1')
/
insert into teste_random
values
('Thiago','2')
/
insert into teste_random
values
('Thiago','3')
/   
insert into teste_random
values
('Edna','1')
/
COMMIT
/


Qual a idéia. Temos 3 registros para o nome “Felipe”, 3 para o nome “Thiago” e 1 registro para o nome “Edna”. Queremos que dentro de um determinado grupo de registros (grupos por nome) seja escolhido um registro aleatório. Exemplo, para o grupo “Felipe”, onde há três registros “Felipe, 1”, “Felipe, 2” e “Felipe, 3”, o programa deve escolher um destes três registros. E faça isso também para os grupos ”Thiago” e “Edna”. No caso do grupo referente ao nome “Edna”, só existe um registro, portanto, sempre vai retornar o mesmo. Quanto aos outros, para cada grupo, em cada execução ele deve trazer um registro aleatoriamente.

Segue o SELECT que fará isto:
select nome, numero
from (
      select nome, numero
            ,rank() over(partition by nome order by numero) rnk
      from   teste_random
     ) a
where  rnk = (select ceil(dbms_random.value(0,(select count(*) from teste_random te2 where te2.nome = a.nome))) from dual)
 


Segue algumas execuções:



Falows!

segunda-feira, 5 de abril de 2010

Parâmetros tipo Data e Numérico vindos do EBS

Opa!


Quando trabalhamos com datas e números, sempre temos que prestar a atenção como estes dados estão chegando ao programa. É comum acontecer os famosos erros de formato referentes a números ou datas inválidas, principalmente, quando estamos construindo um determinado programa onde temos que passar estes valores para outros programas através de parâmetros.  Um problema muito comum acontece quando estamos trabalhando com concorrentes no EBS passando parâmetros para programas armazenados no banco. Segue abaixo os passos para solucionar estes problemas:


1) O primeiro passo é, quando for definir os parâmetros de um programa concorrente, colocar como listas de valores, as nativas do Oracle, FND_NUMBER e FND_STANDARD_DATE para os tipos NUMBER e DATE, respectivamente.

2) No seu programa armazenado em banco, numa PROCEDURE, por exemplo, crie os parâmetros que receberão os dados, declarando-os com o tipo VARCHAR2.

3) Dentro do seu programa utilize as funções abaixo para a conversão:


Exemplo 1 (utilização no corpo do programa):
...
  wvl_item number;
  wdt_hoje date;
  --
begin
  -- No caso de conversão para números.
  wvl_item := fnd_number.canonical_to_number(pvl_item); -- pvl_item: parâmetro do tipo varchar2.
  --
  -- No caso de conversão para data.
  wdt_hoje := fnd_date.canonical_to_date(pdt_entrega); -- pdt_entrega: parâmetro do tipo VARCHAR2.
end;


Exemplo 2 (utilização na área de declaração de variáveis):
...
  wvl_item number default fnd_number.canonical_to_number(pvl_item);
  wdt_hoje date   :=      fnd_date.canonical_to_date(pdt_entrega);
  --
begin
  ...
  ...
  ...
end;


O contrário também pode ser feito com a mesma função. Converter um numérico ou data para string:
...
  wvl_item varchar2(38);
  wdt_hoje varchar2(20);
  --
begin
  -- No caso de conversão para caracter.
  wvl_item := fnd_number.number_to_canonical(vl_item);
  --
  -- No caso de conversão para caracter.
  wdt_hoje := fnd_date.date_to_canonical(sysdate);
end;


O segredo destas funções é que as mesmas são específicas para o EBS, logo elas “sabem”, digamos assim, qual o formato que a suíte está trabalhando. Se você quiser saber quais são estes formatos, uma dica é verificar no LOG do concorrente as informações a respeito dos parâmetros passados para o concorrente no momento da execução, lá ele mostra cada parâmetro com seu respectivo valor informado. Note que ele não passa os valores no formato que escolhemos na janela de parâmetros do concorrente e sim no formato que ele está trabalhando em background.


Forte abraço!

sábado, 27 de março de 2010

Visualizando Perfis do EBS por Nível Hierárquico

Opa!

A seguir uma QUERY muito completa e interessante, onde ao informarmos uma string, ela pesquisa por todos os perfis correspondentes, mostrando seus valores em todos os níveis que o perfil existir. O % pode ser usado para tornar abrangente a pesquisa.

Segue script: http://www.ewginfo.com.br/askedu/profile_query.sql

Falows!

Configurando Informações de Impressão para um Concurrent (EBS) em Tempo de Execução

Opa!

Às vezes acontece a seguinte necessidade, temos um concorrente que chama um programa, por exemplo, uma PACKAGE, e esta, por sua vez, além de processar determinados dados, chama um ou mais concorrentes. Entretanto, algumas informações como, por exemplo, número de cópias para impressão, estilo de impressão e a própria impressora, podem ser mudados quando executamos um concorrente. Quando isto acontece precisamos levar estas novas configurações, escolhidas no momento da execução, para os concorrentes que serão executados pela PACKAGE. Abaixo segue um exemplo de como isto pode ser feito. Pense neste exemplo como sendo parte de um programa, que está sendo chamado através de um concorrente, onde este mesmo programa chamará outro concorrente.  Neste caso, precisamos passar as configurações escolhidas para ele, caso contrário ele utilizará as informações padrões, configuradas em seu cadastro. Fazemos isto através da função: FND_REQUEST.SET_PRINT_OPTIONS.

...
begin
  --
  -- Recuperando informações de impressão do concorrente corrente.
  --
  select printer
        ,number_of_copies
        ,print_style
  into   w_impressora
        ,w_num_copias
        ,w_estilo
  from   fnd_concurrent_requests
  where  request_id = fnd_global.conc_request_id;
  -- =======================================================================================
  -- Chamando função para configurar impressora, estilo e número de cópias.
  --
  w_conf_impres := fnd_request.set_print_options( printer   => w_impressora
                                                 ,style     => w_estilo
                                                 ,copies    => w_num_copias
                                                 );
  -- =======================================================================================
  --
  --
  -- Chamando Concurrent.
  wid_solicitacao := fnd_request.submit_request( 'ABC' -- short name da aplicação.
                                                ,'DEF' -- short name do programa.
                                                ,''
                                                ,''
                                                ,false
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0) ,chr(0)
                                                );
  --
  if wid_solicitacao = 0 then
    --
    fnd_file.put_line(fnd_file.log,'Não foi possível executar o concorrente DEF.');
    --
  else
    --
    fnd_file.put_line(fnd_file.log,'Concorrente DEF executado: '||wid_solicitacao);
    --
  end if;
  --
exception
  when others then
    fnd_file.put_line(fnd_file.log,'Erro ao executar concorrente DEF: '||sqlerrm);
end;
...


Forte abraço!