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!

sexta-feira, 26 de março de 2010

Cadastrando um Perfil com Lista de Valores no EBS

Olá!

Hoje vamos ver como se cadastra um perfil no EBS e também agregarmos uma lista de valores a ele. Para cadastrarmos um perfil vamos acessar o EBS na responsabilidade “Desenvolvedor de Aplicações”, opção do menu, “Perfil”.  Abaixo segue um print com um exemplo de um perfil para guardar o código de uma retenção do OM.


Note que existem ali algumas informações que precisam ser cadastradas. Onde:

Nome: Um nome para a retenção. Este nome serve mais ou menos como código, portanto, recomendo colocar nomes simples, sem acento, espaço ou caracteres especiais.

Aplicação: Neste campo associamos a qual aplicação ele pertence. Como retenções fazem parte do OM, e nossa lista de valores também provém de dados desta aplicação, colocamos “Order Management”.

Nome de Perfil do Usuário: Aqui é colocado um nome breve, que apenas descreva com poucas palavras um descritivo referente ao perfil. OBS: É este o nome que vamos utilizar para pesquisar o perfil e cadastrar um valor para ele mais adiante.

Descrição: Neste campo colocamos uma descrição do que se trata o perfil. Aqui é o momento de colocar uma descrição que explique com mais detalhes o objetivo do perfil.

Data de Ativação: Aqui pode ser definida uma data Inicial e Final de ativação do perfil, ou seja, o período que ele estará ativo.

Validação SQL: Neste ponto fica interessante. É aqui que vamos colocar o SELECT que será a base para nossa lista de valores. Abaixo segue o código e seus detalhes:

SQL=" SELECT NAME,HOLD_ID
INTO  :visible_option_value,:profile_option_value
FROM  OE_HOLD_DEFINITIONS
WHERE (TRUNC(START_DATE_ACTIVE) <= TRUNC(SYSDATE)
      OR START_DATE_ACTIVE IS NULL)
AND   (TRUNC(END_DATE_ACTIVE) >= TRUNC(SYSDATE)
      OR END_DATE_ACTIVE IS NULL)
ORDER BY 1"
TITLE="Retenções"
HEADING="N"
COLUMN="NAME(100)"



No SELECT que utilizamos existem algumas informações que devem ser observadas. Temos a tag SQL, digamos assim, que recebe a nossa QUERY, propriamente dita. Note que em conjunto com ela, existe a cláusula INTO que vai receber os valores vindos do SELECT. Depois podemos definir um título através da tag TITLE, que será o título da lista de valores. Temos também as tags HEADING E COLUMN, que são utilizadas para definir se aparecerá a descrição da coluna na lista de valores e também definir o tamanho desta coluna, respectivamente. Para definir o tamanho da coluna você informa o nome da coluna referenciada no SELECT e entre parênteses o tamanho.

Tipo de Hierarquia: Neste ponto você escolhe os níveis de acesso por tipo de hierarquia. Sendo por acesso Local ou pela Aplicação, Responsabilidade, Servidor, Organização ou Usuário. Note que dependendo do tipo escolhido, o quadro “Nível de Acesso do Tipo de Hierarquia” vai apresentando as opções que podem ser configuradas. Geralmente, para nossas aplicações, utilizamos o tipo “Segurança”. Os níveis de hierarquia são utilizados para que você possa definir diversos valores e acessos em determinados pontos, como por exemplo, definir um valor a nível de usuário, de responsabilidade e assim por diante.

Acesso ao Usuário: Neste ponto você define se o usuário pode ou não visualizar o perfil e se poderá além de visualizar também alterá-lo.

Acesso ao Programa: Semelhante à definição realizada em Acesso ao Usuário, visto acima.

Agora, depois de cadastrado, vamos definir um valor para este perfil e verificar se nossa lista de valores foi criada de forma correta. Para isto acesse a responsabilidade “Administrador do Sistema”, opção do menu, “Perfil > Sistema”. A opção “Pessoal” serve para cadastrar o valor para o perfil, no usuário conectado. Caso você tenha habilitado o usuário para visualizar e/ou alterar, é por aqui que ele pode ser isto. Em outras responsabilidades também é possível fazer isto, através do menu “Editar > Preferências > Perfis”. Assim que clicarmos na opção “Sistema”, as telas abaixo são apresentadas:

 

O nível de hierarquia, ou seja, por onde o Oracle começa a procurar valores setados, segue da seguinte forma:

- Local
  - Servidor
     - Organização/Aplicação
        - Responsabilidade
         - Usuário


Seguindo esta hierarquia, o Oracle começa a verificar (debaixo para cima) onde pode existir um valor cadastrado. Exemplo, se não achar no Usuário, procura na Responsabilidade, se não achar na Responsabilidade, procura na Organização/Aplicação até chegar ao último nível.

Voltando ao nosso exemplo, na tela de localização de valores, deixe a opção Local marcada (já vem como default, senão marque) e no campo Perfil, próximo ao botão Localizar, preencha com o valor que inserimos no cadastrado do perfil, campo “Nome de Perfil do Usuário”. No nosso caso, o valor “Retençoes”. Depois disso clique no botão Localizar. Isto fará com que a tela de valores do perfil seja aberta. Posicione o cursor no campo Local. Note que dentro do campo aparece o botão típico de chamada para Lista de Valores. Veja como ficou nossa lista:

 

Neste exemplo cadastramos um valor para Local, mas poderíamos cadastrar para qualquer outro, como para Responsabilidade ou Aplicação. Basta marcar as caixas correspondentes e cadastrar os valores na tela, conforme print acima.

Obs.: Para definição de perfis a nível de Servidor e Aplicação, quando usados juntos, podem existir restrições. Acesse a documentação da Oracle para estar por dentro de mais detalhes.

Falows!

 

terça-feira, 23 de março de 2010

Gerando um Array de Datas

Hi!

Abaixo segue um jeito simples de gerarmos um array de datas através de um comando SELECT, e, diga-se de passagem, um jeito simples e esperto!

select (to_char (sysdate - 1 + level, 'dd-mon-rrrr'))    date_range
      ,(to_char (sysdate - 1 + level, 'month, dd rrrr')) date_word
from   dual connect by level <= 5 -- (número de dias a ser gerado)


Segue o resultado:


Contribuição: Romeu Schiessel Junior.

Abraço!

segunda-feira, 22 de março de 2010

Simulando sessão Oracle Application em Ferramentas de acesso a Banco de Dados

Hi!

Algumas vezes necessitamos executar programas ou SELECTS direto no banco de dados, ou seja, por fora do Aplicativo Oracle, através de ferramentas como SQL Navigator, SQL Tools, PL/SQL Developer ou outras ferramentas do gênero. Quase sempre, para VIEWS que são utilizadas no EBS, é necessário que o ambiente esteja com algumas variáveis “setadas” para que possamos visualizar os dados. Caso contrário, nossa QUERY ou programa não retorna nada. Segue abaixo um SCRIPT que sempre uso e que prepara o ambiente como se estivéssemos conectados no Oracle Applications. Ele funciona para 99% dos casos. Salvo outros procedimentos mais específicos que podem ocorrer dependendo do módulo e responsabilidade que desejamos acessar. Execute este SCRIPT na ferramenta que você estiver utilizando para acessar o banco de dados e substitua as varáveis: '&user_name' e '&responsibility_key' pelo nome do usuário e chave da responsabilidade, respectivamente. Este último você encontra no cadastro de responsabilidades no Administrado do Sistema.

declare
  p_application_id     number;
  p_responsibility_id  number;
  p_responsibility_key varchar2(200);
  p_user_id            number;
  p_user_name          varchar2(200);
  p_org_id             number;
begin
  --
  begin
    p_user_name := '&user_name';
    --
    select user_id
    into   p_user_id
    from   fnd_user
    where  user_name = p_user_name;
  exception
    when no_data_found then
      raise_application_error(-20001,'Usuário não encontrado: '||p_user_name);
    when others then
      raise_application_error(-20002,'Erro ao recuperar o id do usuário '||p_user_name||'. Erro: '||sqlerrm);
  end;
  --
  begin
    p_responsibility_key := '&responsibility_key';
    --
    select application_id
          ,responsibility_id
    into   p_application_id
          ,p_responsibility_id
    from   fnd_responsibility
    where  responsibility_key = p_responsibility_key;
  exception
    when no_data_found then
      raise_application_error(-20003,'Responsabilidade não encontrada: '||p_responsibility_key);
    when others then
      raise_application_error(-20004,'Erro ao recuperar o id da responsabilidade '||p_responsibility_key||'. Erro: '||sqlerrm);
  end;
  --
  begin
    fnd_client_info.setup_client_info( p_application_id
                                      ,p_responsibility_id
                                      ,p_user_id
                                      ,0);
  exception
    when others then
      raise_application_error(-20005,'Erro ao configurar variáveis de sessão (FND_CLIENT_INFO.SETUP_CLIENT_INFO). Erro: '||sqlerrm);
  end;
  --
  begin
    fnd_global.apps_initialize( p_user_id
                               ,p_responsibility_id
                               ,p_application_id
                               ,0);
  exception
    when others then
      raise_application_error(-20006,'Erro ao configurar variáveis de sessão (FND_GLOBAL.APPS_INITIALIZE). Erro: '||sqlerrm);
  end;
  --
  begin
    p_org_id := &p_org_id;
    --
    -- Para versão R12 do Oracle Applications (caso não seja, comente esta parte)
    mo_global.set_policy_context( p_access_mode  => 'S'
                                 ,p_org_id       => p_org_id);
  exception
    when others then
      raise_application_error(-20007,'Erro ao configurar variáveis de sessão (MO_GLOBAL.SET_POLICY_CONTEXT). Erro: '||sqlerrm);
  end;
end;


Obs.: Note que existe um adendo no código, para a versão R12 do Oracle Applications.

Falows!

sábado, 20 de março de 2010

Recuperar dados das Listas de Valores cadastradas no Oracle EBS

Opa!

Segue QUERY para recuperar os valores referentes às listas de valores cadastradas no Oracle EBS.

select b.flex_value
      ,t.description
from   fnd_flex_values_tl  t
      ,fnd_flex_values     b
      ,fnd_flex_value_sets s
where  b.flex_value_id     = t.flex_value_id
and    t.language          = userenv('LANG')
and    b.flex_value_set_id = s.flex_value_set_id
and    flex_value_set_name = &lista
and    trunc(sysdate)      between nvl(start_date_active, trunc(sysdate))
                           and     nvl(end_date_active, trunc(sysdate))
and    b.enabled_flag      = 'Y'
order  by t.description


Falows!

Como localizar arquivos gerados pelo Trace

Opa!

Quando queremos analisar o desempenho de um programa, utilizamos um processo chamado TRACE. O TRACE analisa a execução de um programa, fornecendo alguns dados para que possamos entender como o otimizador do banco de dados executou determinados comandos SQL que por ventura existam dentro do programa que esta sendo monitorado. Estes dados são guardados dentro de um arquivo com a extensão “.trc”, que fica gravado em um diretório do servidor. A QUERY abaixo pode ser utilizada para mostrar onde estes arquivos foram gerados e salvos. Basta informarmos o id da solicitação (id do concorrente), representado na QUERY por “&request”.

select 'Request id: '||request_id ,
       'Trace   id: '||oracle_Process_id,
       'Trace Flag: '||req.enable_trace,
       'Trace Name: '||dest.value||'/'||lower(dbnm.value)||'_ora_'||oracle_process_id||'.trc',
       'Prog. Name: '||prog.user_concurrent_program_name,
       'File  Name: '||execname.execution_file_name|| execname.subroutine_name ,
       'Status    : '||decode(phase_code,'R','Running') ||'-'||decode(status_code,'R','Normal'),
       'SID Serial: '||ses.sid||','|| ses.serial#,
       'Module    : '||ses.module
from   fnd_concurrent_requests req
      ,v$session               ses
      ,v$process               proc
      ,v$parameter dest
      ,v$parameter dbnm
      ,fnd_concurrent_programs_vl prog
      ,fnd_executables execname
where  req.request_id             = &request
and    req.oracle_process_id      = proc.spid(+)
and    proc.addr                  = ses.paddr(+)
and    dest.name                  = 'user_dump_dest'
and    dbnm.name                  = 'db_name'
and    req.concurrent_program_id  = prog.concurrent_program_id
and    req.program_application_id = prog.application_id
and    prog.application_id        = execname.application_id
and    prog.executable_id         = execname.executable_id


Embora, nosso exemplo esteja sendo focado para o Oracle Application, o comando TRACE pode ser utilizado para outros programas e comandos SQL que não fazem parte desta suíte de aplicativos.
 

Forte abraço!

Como extrair números de uma String de Caracteres

Bem pessoal,
Estes dias recebi esta dica de um amigo e achei muito interessante. Às vezes você precisa, dentro de um programa, extrair tudo que é número de uma string de caracteres e acha que para isto é necessário fazer um PL. Veja no exemplo abaixo, que com um simples SELECT foi possível fazer isto através do comando TRANSLATE.

select  translate(endereco, '1234567890', ' ') so_letras
       ,ltrim(translate(endereco, translate(endereco, '1234567890', ' ') , ' ')) so_numeros
from   (select '65 HG5IS 258 KS34 LKJ4 AS 21DF G AÇ K43 ' endereco
        from dual)


O comando TRANSLATE, pra quem não lembra, tem o objetivo de substituir ocorrências de um determinado conjunto, com relação a um segundo conjunto de caracteres. E é isso que acontece neste exemplo. Note que, na primeira coluna do SELECT o comando substitui tudo que é número, varrendo cada caracter da string contida na coluna ENDERECO, por espaço em branco. Com isto temos o resultado mostrando apenas os caracteres que não são números. Depois aplicamos novamente o comando TRANSLATE em cima deste resultado, mas agora, substituindo tudo que não é numérico, também por espaços em branco. No resultado final você tem números de um lado e os caracteres que não são números de outro.

É isso.
Abraço!

sexta-feira, 19 de março de 2010

Olá, Pessoal!


Infelizmente, com a experiência também vem a velhice e a memória vai ficando mais lenta. Para resolver este problema criei este blog... pra que mesmo? Ah! Lembrei...rs! Para postar dicas, truques e outros assuntos relacionados a tecnologia Oracle. Além de uma forma de consulta, também servirá para ajudar os amigos que se interessam por este assunto. Nos próximo dias estarei postando algo aqui. Fiquem a vontade para mandar sugestões de assuntos, críticas, ou seja, ajudar no crescimento do conhecimento. Forte abraço.

Eduardo Gonçalves