четверг, 27 декабря 2012 г.

Объект DIRECTORY в ORACLE

Объект базы данных DIRECTORY - это ссылка на каталог сервера, на котором работает инстанс Oracle. Он нужен для пакета UTL_FILE, работы утилит impdp/expdp, при использовании полей типа BFILE в таблицах, а также при создании внешних таблиц (external tables).
Вот что можно делать с объектом DIRECTORY:


Пара замечаний:
  • При создании директории ORACLE не проверяет её наличие и доступность, поэтому о создании каталога на диске и предоставлении прав на него пользователю-владельцу инстанса надо позаботиться заранее. Если этого не сделать, то при попытке обращения получим ошибку.
  • При удалении директории всё её содержимое остаётся в файловой системе.
  • Надо с осторожностью раздавать пользователям привилегию CREATE ANY DIRECTORY, так как у них появится возможность изменять любые файлы ОС, к которым есть доступ у пользователя-владельца инстанса

Регистрация приложения OEBS

Источники:

http://onlineappsdba.blogspot.com/2007/10/creating-custom-application-in-oracle.html
http://apps-oracle.ru/registration_application/
http://www.appshosting.com/pub_doc/custom_top.html

Кратко

  1. Создать структуру каталогов
  2. Изменить файл (по умолчанию defaults.env) настроек переменных окружения для сервера форм. Его имя хранится в переменной окружения envFile в файле appsweb.cfg, имя и путь к которому в свою очередь хранятся в переменной окружения  FORMS_WEB_CONFIG_FILE, добавив строку с установкой значения переменной окружения <префикс приложения (ЗАГЛАВНЫМИ)>_TOP. Тем самым будет определён каталог, в котором сервер Oracle Forms сможет найти файлы приложения
  3. В файл $APPL_TOP/custom<имя инстанса>.env следует добавить инициализацию тех же переменных с последующим их экспортом (это необходимо для выполнения системных процедур и вызова параллельных запросов) и проверить наличие вызова это файла из $APPL_TOP/APPS<имя инстанса>.env. При наличии в составе приложения исполняемых операционной системой программ также следует добавлять <префикс приложения (ЗАГЛАВНЫМИ)>_TOP/bin к переменной окружения PATH (если используется)
  4. Остановить менеджер параллельных программ (concurrent manager)
    $ADMIN_SCRIPTS_HOME/adcmctl.sh stop apps/apps
  5. Выполнить файл, замещающий APPLSYS.env
    . / $APPL_TOP/APPS<имя инстанса>.env
  6. Перезапустить concurrent manager
    $ADMIN_SCRIPTS_HOME/adcmctl.sh start apps/apps
  7. Войдите в систему с полномочиями Разработчик приложений (Application Developer) и зарегистрируйте приложение
  8. Войдите в систему с полномочиями System Administrator и добавьте приложение в группу данных (раздел меню «Security : ORACLE», пункт «Группа данных»)

Подробнее

Custom Applications are required if you are creating new forms, reports, etc.   
This allows you to segregate your custom written files from the standard seeded functionality that
Oracle Applications provide.     
Customizations can therefore be preserved when applying patches or upgrades to your environment. 
1)  Make the directory structure for your custom application files.
               cd $APPL_TOP
               mkdir fz
               mkdir fz/11.5.0
               mkdir fz/11.5.0/admin
               mkdir fz/11.5.0/admin/sql
               mkdir fz/11.5.0/admin/odf
               mkdir fz/11.5.0/sql
               mkdir fz/11.5.0/bin
               mkdir fz/11.5.0/reports
               mkdir fz/11.5.0/reports/US
               mkdir fz/11.5.0/forms
               mkdir fz/11.5.0/forms/US 
               mkdir fz/11.5.0/$APPLLIB
               mkdir fz/11.5.0/$APPLOUT
               mkdir fz/11.5.0/$APPLLOG 
2)  Add the custom module into the environment
Apply ADX.E.1 and add the entry to topfile.txt as a standard product top entry .   
Customised environment variables can be added to AutoConfig by using the filename specificed by s_custom_file, 
which is then called from the APPSORA.env file. 
If using Forms Listener Servlet, you may also need to add $CUSTOM_TOP to formsservlet.ini in
$APACHE_TOP/Jserv/etc 
3)  Create new tablespace for database objects
     create tablespace FZ datafile '/u01/oracle/visdata/fz.dbf' size 10M default storage(initial 10k next 10k)
4)  Create schema
               create user fz identified by fz
                               default tablespace fz
                               temporary tablespace temp
                               quota unlimited on fz
                               quota unlimited on temp;
               grant connect, resource to fz;
5)  Register your Oracle Schema. 
     Login to Applications with System Administrator responsibility
     Navigate to Application-->Register
               Application = FZ Custom
               Short Name  = FZ
               Basepath    = FZ_TOP
               Description = FZ Custom Application
6)  Register Oracle User
     Naviate to Security-->Oracle-->Register
               Database User Name = FZ
               Password           = FZ
               Privilege          = Enabled
               Install Group      = 0
               Description        = FZ Custom Application User
7)  Add Application to a Data Group
     Navigate to Security-->Oracle-->DataGroup
               Data Group  = FZGroup
               Description = FZ Custom Data Group
      Click on "Copy Applications from" and pick Standard data Group, then add the following entry.
               Application = FZ Custom
               Oracle ID   = APPS
               Description = FZ Custom Application
8)  Create custom request group
     This will act as a placeholder for any custom reports we wish to make available for the Custom Responsibility 
      Navigate to Security-->responsbility-->Request
               Group       = FZ Request Group
               Application = FZ Custom
               Code        = FZ
               Description = FZ Custom Requests
       We will not define any requests to add to the group at this stage, but you can add some now if required.
9)  Create custom menu
      This will act as a placeholder for any menu items we wish to make available for the Custom Responsibility. 
      We will create two menus, one for Core Applications and one for Self Service.
       Navigate to Application-->Menu
               Menu           = FZ_CUSTOM_MENU
               User Menu Name = FZ Custom Application
               Menu Type      = <leave blank>
               Description    = FZ Custom Application Menu
               Seq         = 100
               Prompt      = View Requests
               Submenu     = <leave blank>
               Function    = View All Concurrent Requests
               Description = View Requests
               Seq         = 110
               Prompt      = Run Requests
               Submenu     = <leave blank>
               Function    = Requests: Submit
               Description = Submit Requests
               Menu           = FZ_CUSTOM_MENU_SSWA
               User Menu Name = FZ Custom Application SSWA
               Menu Type      = <leave blank>
               Description    = FZ Custom Application Menu for SSWA 
10)  Create new responsibility.   One for Core Applications and One for Self Service (SSWA)
       Navigate to Security-->Responsibility-->Define
               Responsibility Name       = FZ Custom
               Application               = FZ Custom
               Responsibility Key        = FZCUSTOM
               Description               = FZ Custom Responsibility
               Available From            = Oracle Applications
               Data Group Name           = fzGroup
               Data Group Application    = FZ Custom
               Menu                      = FZ Custom Application
               Request Group Name        = FZ Request Group
 
               Responsibility Name       = FZ Custom SSWA
               Application               = FZ Custom
               Responsibility Key        = FZCUSTOMSSWA
               Description               = FZ Custom Responsibility SSWA
               Available From            = Oracle Self Service Web Applications
               Data Group Name           = fzGroup
               Data Group Application    = FZ Custom
               Menu                      = FZ Custom Application SSWA
               Request Group Name        = FZ Request Group
11)  Add responsibility to user
       Navigate to Security-->User-->Define
       Add FZ Custom responsibility to users as required.
12)  Other considerations
       You are now ready to create your database Objects, custom Reports, Forms, Packages, etc
Create the source code files in the FZ_TOP directory appropriate for the type of object.   For example forms
would be located in $FZ_TOP/forms/US or package source code in $FZ_TOP/admin/sql for example.
Database Objects, such as tables, indexes and sequences should be created in the FZ schema, then you need to 
               a) Grant all privilege from each custom data object to the APPS schema.
                               For example :  logged in as FZ user
                                              grant all privileges on myTable to apps;
               b) Create a synonym in APPS for each custom data object
                               For example :  logged in as APPS user
                                              create synonym myTable for fz.myTable;
Other database objects, such as views and packages should be created directly in the APPS schema.


понедельник, 17 декабря 2012 г.

Регистрация формы в ОЕБС

Для регистрации формы, разработанной в 6 версии Oracle Forms используем:


f60gen module=<FORM_NAME> userid=APPS/apps Module_Type=FORM Output_File=$<PRODUCT>_TOP/forms/US/<FORM_NAME>.fmx


Для регистрации формы, разработанной в 10 версии Oracle Forms используем:

frmcmp_batch module=$AU_TOP/forms/RU/XX_CITY.fmb userid=apps/apps module_type=FORM Compile_All=YES output_file=$AU_TOP/forms/RU/XX_CITY.fmx

четверг, 6 декабря 2012 г.

Трассировка сессии

Трассировка сессии Oracle помогает найти проблемные запросы и понять в чем именно причина.

Что именно будет записываться в трассировочный файл, определяется номером события (event).
Стандартный номер события 10046. Именно такой уровень устанавливается при выполнении команды1 alter session set sql_trace=true;


Список данных событий и для чего они предназначены можно посмотреть здесь EventReference



Событие трассировки 10046 / Trace event 10046

Включить трассировку в текущей сессии1 alter session set events '10046 trace name context forever, level 1';


выключить трассировку в текущей сессии1 alter session set events '10046 trace name context off';


Уровни:
0 – трассировка отключена
1 – стандартная трассировка
4 – добавлены значения связываемых (binds) переменных
8 – добавлены события ожидания (waits)
12 – связываемые переменные + события ожидания

Для включения трассировки в другой сессии можно воспользоваться командой1 sys.dbms_system.set_ev(sid, serial#, 10046, 12, '');


Путь к директории, где появится файл трассировки1 select value from v$parameter where name = 'user_dump_dest';


Задать имя для trace файла1 alter session set tracefile_identifier = 'mytrace1';




Понимание трасировочного файла


Выполняем следующий код, чтобы создать trace файл:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 SET SERVEROUTPUT ON
alter session set tracefile_identifier = 'mytrace2'
/
alter session set events '10046 trace name context forever, level 12'
/
declare
l_row_num number;
l_owner varchar2(10) := 'SYS';
begin
select count(1) into l_row_num from all_tables t where t.owner = l_owner;
dbms_output.put_line('num='||l_row_num);
end;
/
alter session set events '10046 trace name context forever, level 0'
/


Заголовок файла – содержит информацию об инстансе и сессии для которой создан1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 Trace file .../"instance_name"_ora_12591_mytrace2.trc
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORACLE_HOME = ...
System name: ...
Node name: ...
Release: ...
Version: ...
Machine: ...
Instance name: "instance_name"
Redo thread mounted by this instance: 1
Oracle process number: 545
Unix process pid: 12591, image: ...

*** 2012-09-19 12:07:49.268
*** SESSION ID:(669.6321) 2012-09-19 12:07:49.268
*** CLIENT ID:() 2012-09-19 12:07:49.268
*** SERVICE NAME:(...) 2012-09-19 12:07:49.268
*** MODULE NAME:(PL/SQL Developer) 2012-09-19 12:07:49.268
*** ACTION NAME:(Command Window - New) 2012-09-19 12:07:49.268


Разбор курсора1
2
3 PARSING IN CURSOR #11529215044981500944 len=54 dep=1 uid=44 oct=3 lid=44 tim=10192202222475 hv=1751201178 ad='c0000005d60dcaf0' sqlid='1f79yzdn62dcu'
SELECT COUNT(1) FROM ALL_TABLES T WHERE T.OWNER = :B1
END OF STMT


cинтаксис1
2
3 PARSING IN CURSOR #[CURSOR] len=X dep=X uid=X oct=X lid=X tim=X hv=X ad='X' sqlid='X'
[statement]
END OF STMT

[CURSOR] – номер курсора
len – длина SQL запроса
dep – рекурсивная глубина SQL запроса
uid – id пользователя (user) под которым был разобран запрос 1 select * from all_users where user_id = :uid;

oct – ID команды oracle. Можно увидеть в V$SQL.COMMAND_TYPE и V$SESSION.COMMAND
lid – ID схемы в которой был разобран запрос. Может отличаться от uid
tim – timestamp, в микросекундах
hv – hash значение, V$SQL.HASH_VALUE
ad – адрес. V$SQL.ADDRESS, V$SQLTEXT.ADDRESS
sqlid – ID запроса, V$SQL.SQL_ID

Основные операции1
2
3 PARSE #11529215044981500944:c=0,e=370,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,plh=0,tim=10192202222474
EXEC #11529215044981500944:c=270000,e=276923,p=0,cr=3,cu=0,mis=1,r=0,dep=1,og=1,plh=242196440,tim=10192202499569
FETCH #11529215044981500944:c=840000,e=1466871,p=2776,cr=71124,cu=0,mis=0,r=1,dep=1,og=1,plh=242196440,tim=10192203966668


PARSE – разбор курсора, EXEC – выполнение курсора, FETCH – получение данных
cинтаксис1
2
3 PARSE #[CURSOR]:c=X,e=X,p=X,cr=X,cu=X,mis=X,r=X,dep=X,og=X,plh=X,tim=X
EXEC #[CURSOR]:c=X,e=X,p=X,cr=X,cu=X,mis=X,r=X,dep=X,og=X,plh=X,tim=X
FETCH #[CURSOR]:c=X,e=X,p=X,cr=X,cu=X,mis=X,r=X,dep=X,og=X,plh=X,tim=X

[CURSOR] – номер курсора
c – время в микросекундах затраченное процессором
e – общее затраченное время в микросекундах
p – число физических чтений (physical reads)
cr – количество блоков полученных в режиме согласованного чтения (retrieved for CR reads)
cu – количество блоков полученных в текущем режиме (retrieved in current mode)
mis – отсутствие курсора в кеше, выполняется hard parse
r – количество возвращаемых строк
dep – рекурсивная глубина запроса
og – Цель оптимизатора: 1=All_Rows, 2=First_Rows, 3=Rule, 4=Choose
plh – Hash значение для выполняемого плана. V$SQL_PLAN.PLAN_HASH_VALUE
tim – timestamp, в микросекундах

Связываемые переменные / binds1
2
3
4
5
6 BINDS #11529215044981500944:
Bind#0
oacdty=01 mxl=32(10) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=01 csi=171 siz=32 off=0
kxsbbbfp=9fffffffbf3b37b8 bln=32 avl=03 flg=09
value="SYS"

[CURSOR] – номер курсора
bind#N – номер переменной
oacdty – тип данных
mxl- maximum length of the bind variable value (private maximum length in parentheses)
mxlc – ?
mal – длина массива
scl – масштаб (scale)
pre – точность (precision)
oacflg – special flag indicating bind options
fl2 – second part of oacflg
frm – ?
csi – идентификатор кодировки
siz – объем выделяемой памяти
off – offset into the chunk of the bind buffer
kxsbbbfp – адрес переменной
bln – длина буфера для переменной
avl – актуальная длина переменной
flg – статус переменной
value- значение переменной

Ожидания / wait1
2 WAIT #11529215044981500944: nam='Disk file operations I/O' ela= 285 FileOperation=2 fileno=4 filetype=2 obj#=397424 tim=10192202526355
WAIT #11529215044981500944: nam='db file sequential read' ela= 583 file#=4 block#=7927 blocks=1 obj#=397424 tim=10192202526996

[CURSOR] – номер курсора
nam- тип ожидания
ela – затраченное время в микросекундах
obj#- номер объекта
tim – timestamp, в микросекундах

Остальные параметры зависят от типа ожидания. Увидеть данные параметры можно с помощью запроса:1 select * from v$event_name where name = :waitname;


План выполнения1
2
3
4
5
6
7
8 STAT #11529215044981500944 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=71124 pr=2776 pw=0 time=1466915 us)'
STAT #11529215044981500944 id=2 cnt=1047 pid=1 pos=1 obj=0 op='FILTER (cr=71124 pr=2776 pw=0 time=1123290 us)'
STAT #11529215044981500944 id=3 cnt=1047 pid=2 pos=1 obj=0 op='NESTED LOOPS OUTER (cr=68261 pr=2735 pw=0 time=1080842 us cost=3024 size=14145 card=115)'
STAT #11529215044981500944 id=4 cnt=1047 pid=3 pos=1 obj=0 op='HASH JOIN RIGHT OUTER (cr=64291 pr=2289 pw=0 time=954642 us cost=2820 size=11322 card=102)'
...
STAT #11529215044981500944 id=9 cnt=28 pid=8 pos=1 obj=16 op='TABLE ACCESS FULL TS$ (cr=33 pr=0 pw=0 time=1609 us cost=8 size=84 card=28)'
STAT #11529215044981500944 id=10 cnt=1047 pid=8 pos=2 obj=0 op='NESTED LOOPS (cr=62544 pr=2252 pw=0 time=561698 us cost=2620 size=8976 card=102)'
...

[CURSOR] – номер курсора
id – номер строки плана
cnt – количество обработанных строк
pid – идентификатор родителя
pos – позиция относительно родителя
obj – ID объекта. ALL_OBJECTS.OBJECT_ID и V$SQL_PLAN.OBJECT#.
op – операция
cr – согласованное чтение (Consistent read)
pr – физическое чтение (Physical reads)
pw – физическая запись (Physical writes)
time – timestamp, в микросекундах
cost – оценка выполнения запроса (CBO)
size – объем данных в байтах
card – число возвращаемых строк

Дополнительно можно почитать ноту Interpreting Raw SQL_TRACE output [ID 39817.1]

среда, 5 декабря 2012 г.

API добавления полномочия для пользователя

С помощью данного API можно добавить полномочие пользователю1

 begin
-- Call the procedure
fnd_user_pkg.addresp(username => :username,
resp_app => :resp_app,
resp_key => :resp_key,
security_group => :security_group, -- в основном 'STANDARD'
description => :description, -- любой коммент
start_date => :start_date,
end_date => :end_date);
commit;
dbms_output.put_line('Responsibility Added Successfully');
exception
when others then
dbms_output.put_line(' Responsibility is not added due to '
|| substr(SQLERRM, 1, 100));
rollback;
end;



И весьма полезный скрипт, c помощью которого можно быстро перетянуть полномочия с одного инстанса на другой.

declare
l_user_name varchar2(100) := 'USER_NAME';
begin
dbms_output.put_line('BEGIN');
-- цикл по списку полномочий пользователя
for i in (select 'fnd_user_pkg.addresp('''||u.user_name||''', '''
|| a.application_short_name ||''', '''
|| r.responsibility_key ||''', '''
|| 'STANDARD' ||''', '''
|| 'Add by script' ||''', '
|| 'sysdate' ||', '
|| 'null' ||');'
as script
, r.responsibility_name
from fnd_user u
,fnd_user_resp_groups g
,fnd_application_vl a
,fnd_responsibility_vl r
where g.user_id(+) = u.user_id
and g.responsibility_application_id = a.application_id
and a.application_id = r.application_id
and g.responsibility_id = r.responsibility_id
AND u.user_name = l_user_name
)
loop
dbms_output.put_line(' dbms_output.put_line('''||i.responsibility_name||''');');
dbms_output.put_line(' '||i.script);
dbms_output.put_line('');
end loop;
dbms_output.put_line(' commit;');
dbms_output.put_line(' dbms_output.put_line('''');');
dbms_output.put_line(' dbms_output.put_line(''Responsibility Added Successfully'');');
dbms_output.put_line('EXCEPTION');
dbms_output.put_line(' when others then');
dbms_output.put_line(' dbms_output.put_line('' Responsibility is not added due to '' || substr(SQLERRM, 1, 100));');
dbms_output.put_line(' rollback;');
dbms_output.put_line('END;');
end;