How to get all the dependencies Oracle object

1. You want to define all used objects, a change which may affect your object:

select 
    level as hlevel, -- dependencies level
    referenced_owner as ref_owner, -- referenced owner name
    lpad(' ', 2*(level-1)) || referenced_name as ref_name,  -- refernced object name
    referenced_type as ref_type, -- referenced object type
    owner parent_owner, -- parent owner name
    name parent_name, - parent object name
    type parent_type -- parent object type
from dba_dependencies
where referenced_owner not in ('SYS', 'SYSTEM', 'PUBLIC')
start with
    owner = :owner -- owner name of your object
    and name = :object -- your object name
connect by owner = prior referenced_owner
    and name = prior referenced_name
    and type = prior referenced_type
ORDER SIBLINGS BY referenced_name; 

2. You want to define all the objects that are affected by changing of your object:

select 
    level as hlevel, -- dependencies level
    owner as parent_owner, -- parent owner name
    lpad(' ', 2*(level-1)) || name as parent_name, -- parent object name
    type as parent_type, -- parent object type
    referenced_owner, -- referenced owner name
    referenced_name, -- referenced object name
    referenced_type -- referenced object type
from dba_dependencies
where referenced_owner not in ('SYS', 'SYSTEM', 'PUBLIC')
start with
    referenced_owner = :owner -- owner name of your object
    and referenced_name = :object -- your object name
connect by prior owner = referenced_owner
    and prior name = referenced_name
    and prior type = referenced_type
ORDER SIBLINGS BY name
; 

 

VBScript collect events print from Windows logs

Скрипт позволяет собирать события печати из журналов Windows с локального или удаленного компьютера(ов) и импортировать их в базу Oracle.

Требования для машины, на которой запускаете скрипт:

  • ОС Windows  (7, XP, Server 2003, Server 2008)
  • Oracle client (or instant client) version 10.2 and above.
  • Запускать скрипт под пользователем, который входит в группу Администрирования на других компьютерах сети.

Требования к базе Oracle:

  • Oracle DB 10.2 and above.
  • Создать в какой-нибудь схеме базы Oracle таблицы:
/* список компьютеров, по которым нужно собирать события печати */
CREATE TABLE PRINTLOG_COMPUTERS
(COMPUTER       VARCHAR2(100));
/* сюда будут писаться данные по печати */
CREATE TABLE PRINTLOG
(SYSDATETIME    DATE,
CREATEDTIME     DATE,
OS              VARCHAR2(50),
EVENTID         NUMBER,
SOURCENAME      VARCHAR2(128),
COMPUTER        VARCHAR2(100),
USERNAME        VARCHAR2(128),
MESSAGE         VARCHAR2(4000));
/* сюда будут писаться ошибки, возникающие при сборе событий */
CREATE TABLE PRINTLOG_ERROR
(SYSDATETIME    DATE,
COMPUTER        VARCHAR2(100),
ERRORMESSAGE    VARCHAR2(512));
  • В таблицу PRINTLOG_COMPUTERS внести имена компьютеров, по которым будет собираться статистика печати.

Требования к компьютерам, с которых будут собираться события печати из журналов Windows:

  • Желательно, чтобы компьютеры были под управлением Windows (7, XP, Server 2003, Server 2008)
  • И чтобы находились в одном домене

Исходник скрипта, с комментариями:

'### [ VBScript ]
'### (c) 02.04.2015
'### What: collects events printing (10, 307) from Windows events logs on local or remote computer and writes them to the Oracle database
'### Author: souluran

Dim objWMIService
Dim colLoggedEvents
Dim colLogFiles
Dim ObjLogFile
Dim objEvent
Dim errCon
Dim errMessage
Dim strSearchString
Dim con
Dim objRecordset
Dim PROC, SQL, ERRINS, INS
Dim objRegistry
Dim strKeyPath
Dim flag
Dim arrSubKeys
Dim subkey
Dim EventCode
Dim LogFile
Dim OverWrite
Const HKEY_LOCAL_MACHINE = &H80000002

On Error Resume Next

'--> connection parameters to Oracle
Driver   = "************" '--> for example "Oracle in instantclient_11_2"
dbName   = "************"
dbUser   = "************" '--> better to have a user with the DBA or have privileges Select/Insert/Delete on tables PRINTLOG_COMPUTERS, PRINTLOG, PRINTLOG_ERROR
Password = "************"
dbSchema = "************" '--> scheme that created the table PRINTLOG_COMPUTERS, PRINTLOG, PRINTLOG_ERROR

'--> open connect to Oracle
Set con = CreateObject("ADODB.Connection")
con.ConnectionTimeOut = 20
con.CommandTimeout = 120
con.Open "Driver={" & Driver & "};DBQ=" & dbName & ";UID=" & dbUser & ";PWD=" & Password

Err.Clear
'--> check connect to Oracle
If Err.Number <> 0 Then
    'error handling:
    errCon = "ORACLE: " & Err.Number & " Srce: " & Err.Source & " Desc: " &  Err.Description
    'WScript.Echo errStr
    Err.Clear
    'WScript.Quit
End If

'--> set the start and the end dates for the collection
begdate = "20150101 00:00:00"
enddate = "20150430 23:59:59"

'--> get list of computers
SQL = "select COMPUTER from " & dbSchema & ".PRINTLOG_COMPUTERS order by 1"
Set objRecordset = con.Execute(SQL)
Do Until objRecordset.EOF
    
    Computer = objRecordset.Fields("COMPUTER").Value
    'WScript.Echo Computer

Err.Clear
    '--> check computer to access
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & Computer & "\root\cimv2")
    If Err.Number <> 0 Then
        errMessage = Err.Description
        'WScript.Echo errMessage
        ERRINS = "INSERT INTO " & dbSchema & ".printlog_error VALUES(sysdate,'" & Computer & "','" & errMessage & "')"
        Set objRecordsetErr = con.Execute(ERRINS)
        Err.Clear
        errMessage = vbNullString
    Else    
        '--> check version OS Windows
        Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
        OS = vbNullString
        For Each objOperatingSystem in colOperatingSystems
            OS = objOperatingSystem.Caption
            Exit For
        Next
        'WScript.Echo OS
        
        '--> set logfile and evencode for Windows XP and 7
        If InStr(OS, "Windows XP") > 0 Or InStr(OS, "Windows(R) XP") > 0 Or
  InStr(OS, "Server 2003") > 0 Then
            LogFile = "System"
            EventCode = "10" 'event print for Windows XP (2003)
        ElseIf InStr(OS, "Windows 7") > 0 Or InStr(OS, "Windows(R) 7") Or InStr(OS, "Server 2008") > 0 Then
            LogFile = "Microsoft-Windows-PrintService/Operational"
            EventCode = "307" 'event print for Windows 7 (2008)
            
            '--> check exists registry key for read printing events on Windows 7
            Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & Computer & "\root\default:StdRegProv")
            strKeyPath = "SYSTEM\CurrentControlSet\services\eventlog"
            objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
            flag = 0
            For Each subkey In arrSubKeys
                If subkey = LogFile Then
                    flag = 1
                    Exit For
                End If
            Next
            
            If flag = 0 Then
                'WScript.Echo "Create new key Microsoft-Windows-PrintService/Operational."
                strKeyPath = "SYSTEM\CurrentControlSet\services\eventlog\Microsoft-Windows-PrintService/Operational"
                objRegistry.CreateKey HKEY_LOCAL_MACHINE, strKeyPath
            End If
        End If
    
        Rec = 0
        '--> check the log for events
        Set colLogFiles = objWMIService.ExecQuery("Select * from Win32_NTLogEvent Where Logfile = '" & LogFile & "' and EventCode = '" & EventCode & "'")
        For Each ObjLogFile In colLogFiles
            Rec = 1
            Exit For
        Next
    
        If Rec = 0 Then
            errMessage = "The " & LogFile & " are failed or not contained events " & EventCode
            'WScript.Echo errMessage
            ERRINS = "INSERT INTO " & dbSchema & ".PRINTLOG_ERROR VALUES(sysdate,'" & Computer & "','" & errMessage & "')"
            Set objRecordsetErr = con.Execute(ERRINS)
            errMessage = vbNullString
        Else 
        
        '--> option overwrite exists records in table (0 - OFF, 1 - ON)
        OverWrite = 0
        If OverWrite = 1 Then
            DEL = "DELETE FROM " & dbSchema & ".PRINTLOG where computer = '" & computer & "' and trunc(CREATEDTIME) >= to_date(substr('" & begdate & "', 1, 8), 'yyyymmdd') " _
                & " and trunc(CREATEDTIME) <= to_date(substr('" & enddate & "', 1, 8), 'yyyymmdd')"
            Set objRecordsetDel = con.Execute(DEL)
        End If

            '--> search events in a given period
            cnt = 0        
            Set colLoggedEvents = objWMIService.ExecQuery("Select * from Win32_NTLogEvent Where Logfile = '" & LogFile & "' and EventCode = '" & EventCode & "' and TimeGenerated >= '"& begdate &"' and TimeGenerated <= '" & enddate & "'")
            cnt = colLoggedEvents.Count
            If cnt > 0 Then
                'WScript.Echo cnt
                For Each objEvent In colLoggedEvents
                     strSearchString = objEvent.Message
                 
                     EventCode = objEvent.EventCode
                     SourceName = objEvent.SourceName
                     If InStr(objEvent.ComputerName, ".keramin.int") > 0 Then
                        ComputerName = LCase(objEvent.ComputerName)
                     Else
                        ComputerName = LCase(objEvent.ComputerName) & ".keramin.int"
                     End If
                     UserName = LCase(objEvent.User)
                     CreatedTime = objEvent.TimeWritten
                     Message = Replace(objEvent.Message, "'", "")
                         
                     INS = "INSERT INTO " & dbSchema & ".PRINTLOG VALUES(sysdate, to_date(substr('" & CreatedTime & "', 1, 14), 'yyyymmddhh24miss'),'" & OS & "','" & EventCode & "','"    & SourceName & "','" & ComputerName & "','" & UserName & "','" & Message & "')"
                     Set objRecordsetIns = con.Execute(INS)
                             
                Next

            Else
                errMessage = "There was no events print in " & LogFile & " from " & begdate & " to " & enddate
                'WScript.Echo errMessage
                'ERRINS = "INSERT INTO " & dbSchema & ".PRINTLOG_ERROR VALUES(sysdate,to_date(substr('" & begdate & "', 1, 8), 'yyyymmdd'),'" & Computer & "','" & errMessage & "')"
                'Set objRecordsetErr = con.Execute(ERRINS)
                errMessage = vbNullString
            End If
        End if
    End If
    
objRecordset.MoveNext
Loop

'--> close connect to Oracle
con.Close
Set objRecordsetErr = Nothing
Set objRecordsetIns = Nothing
Set objRecordsetDel = Nothing
Set con = Nothing
 >        End if
    End If
    
objRecordset.MoveNext
Loop

'--> close connect to Oracle
con.Close
Set objRecordsetErr = Nothing

А вот маленький запрос =), который возвращает нужные для статистики данные по таблице PRINTLOG:

SELECT SYSDATETIME,
         CREATEDTIME,
         EVENTID,
         SOURCENAME,
         COMPUTER,
         OS,
         USERNAME,
         SUBSTR (
            REGEXP_REPLACE (MESSAGE,
                            'Документ \d+, |Document \d+, ',
                            ''),
            1,
              REGEXP_INSTR (
                 REGEXP_REPLACE (MESSAGE,
                                 'Документ \d+, |Document \d+, ',
                                 ''),
                 'владельца|owned|, которым владеет')
            - 1)
            DOC,
         REGEXP_REPLACE (
            TRIM (
               REGEXP_REPLACE (
                  SUBSTR (
                     MESSAGE,
                     REGEXP_INSTR (
                        MESSAGE,
                        'владельца|owned by|, которым владеет')),
                  'владельца |owned by |, которым владеет')),
            ' (.*)')
            OWNER,
         SUBSTR (
            REGEXP_REPLACE (
               SUBSTR (
                  MESSAGE,
                  REGEXP_INSTR (
                     MESSAGE,
                     'напечатан на |был распечатан на |was printed ')),
               'напечатан на |был распечатан на |was printed on '),
            1,
              REGEXP_INSTR (
                 REGEXP_REPLACE (
                    SUBSTR (
                       MESSAGE,
                       REGEXP_INSTR (
                          MESSAGE,
                          'напечатан на |был распечатан на |was printed on ')),
                    'напечатан на |был распечатан на |was printed on '),
                 'через порт|via port|through port')
            - 2)
            PRINTER,
         SUBSTR (
            REGEXP_REPLACE (
               SUBSTR (
                  MESSAGE,
                  REGEXP_INSTR (MESSAGE,
                                'через порт |via port |through port ')),
               'через порт |via port |through port '),
            1,
              REGEXP_INSTR (
                 REGEXP_REPLACE (
                    SUBSTR (
                       MESSAGE,
                       REGEXP_INSTR (
                          MESSAGE,
                          'через порт |via port |through port ')),
                    'через порт |via port |through port '),
                 ' Размер: | Размер в байтах: | Size in bytes: ')
            - 3)
            PORT,
         SUBSTR (
            REGEXP_REPLACE (
               SUBSTR (
                  MESSAGE,
                  REGEXP_INSTR (
                     MESSAGE,
                     'Размер: |Размер в байтах: |Size in bytes: ')),
               'Размер: |Размер в байтах: |Size in bytes: '),
            1,
              REGEXP_INSTR (
                 REGEXP_REPLACE (
                    SUBSTR (
                       MESSAGE,
                       REGEXP_INSTR (
                          MESSAGE,
                          'Размер: | Размер в байтах: | Size in bytes: ')),
                    'Размер: | Размер в байтах: | Size in bytes: '),
                 ' байт;|число страниц: |(.|;) Pages printed: |(.|;) Страниц напечатано: ')
            - 1)
            BYTES,
         TRIM (
            REGEXP_REPLACE (
               SUBSTR (
                  MESSAGE,
                  REGEXP_INSTR (
                     MESSAGE,
                     ' байт; |число страниц: | Pages printed: | Страниц напечатано: ')),
                  ' байт; |число страниц: |Страниц напечатано: |(p|P)ages printed: |[.] Действий пользователя не требуется[.]|[.] No user action is required[.]|'
               || CHR (13)
               || CHR (10)))
            PAGES,
         MESSAGE
FROM printlog
ORDER BY 1;

Если будут какие-то вопросы обращайтесь, возможно помогу.
Также в скором времени создам пост с подобный скриптом, но написанном на Python.

Real-Time segments statistics

bdt's blog

The v$segment_statistics and v$segstat views are a goldmine to extract statistics that are associated with the Oracle segments.

You can see how useful it could be in those posts :

Kevin Closson’s post

Jonathan Lewis’s post or this one

Arup Nanda’s post

But those views are cumulatives, so not so helpful to report real-time information on the segments (Imagine your database is generating a lot of I/O right now and you would like to know wich segments are generating those I/O).

To report real-time statistics on the segments I wrote the segments stats.pl script (click on the link and then on the view source button to copy/paste the source code) that basically takes a snapshot based on the v$segstat view each second (default interval) and computes the differences with the previous snapshot.

Let’s see an example:

./segments_stats.pl Connecting to the Instance... 07:10:45 INST_NAME OWNER OBJECT_NAME STAT_NAME VALUE 07:10:45 BDT1 BDT BDTTAB…

View original post ещё 304 слова

SPM подходы к изменению плана запроса с hardcoded подсказками

Oracle mechanics

Вопрос: как максимально корректно изменить план выполнения уже хинтованного запроса? Корректно, в смысле не меняя текста запроса (само собой) и, желательно, не меняя параметров сессии, т.е. используя, например, безконтактный SQL Plan Management (SPM)?

Простейшая тестовая схема:

Простой запрос с использованием FTS:

View original post ещё 583 слова

ASH-трассировка PL/SQL

Oracle mechanics

К примеру, в AWR-отчёте бд ERP-системы на первом месте видно продолжающееся/неоконченное выполнение процедуры, лидирующей по использованному DB Time с большим отрывом от ближайшего преследователя — 72% против 18%:

Для быстрой оценки такого рода проблем написал скрипт ash_plsqlmon_hist.sql, который по истории ASH вначале показывает суммарный вклад запросов и PL/SQL блоков по частоте попадания в историю ASH (ASH_ROWS), кол-во зафиксированных неповторяющихся выполнений (EXECS), затем — мин/мах время наблюдения(с соответствующими названиями столбцов) и общий профиль ожиданий (WAIT_PROFILE) примерно так:

View original post ещё 277 слов

ERP Галактика — не пускает пользователей (ORA-20001: RECORD LOCKED)

  • В моем случае ERP Галактика на базе Oracle 11g

Произошел разрыв по сети между сервером ERP Галактика и сервером СУБД Oracle. После сбоя новые подключения от пользователей (кроме администраторов) к ERP Галактика перестали устанавливаться. В логе моей базы Oracle alert_[db_name].log стали появляться сообщения подобного вида:

Errors in file x:\oracle\11.2.0\diag\rdbms\gal\trace\gal_ora_3688.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: RECORD LOCKED AAALsvAAFAAAACHAAB
ORA-06512: at «GAL.ALX$ACTIVEUSERS», line 1
ORA-04088: error during execution of trigger ‘GAL.ALX$ACTIVEUSERS’
ORA-06512: at «GAL.GAL_SYSFUNC_PKG», line 1
ORA-06512: at line 1

где GAL — это схема базы Oracle, где хранятся все данные ERP Галактика.
Триггер GAL.ALX$ACTIVEUSERS установлен на таблицу GAL.X$ACTIVEUSERS, через которую отслеживаются и устанавливаются новые подключения пользователей ERP Галактики. Следовательно строка с ROWID AAALsvAAFAAAACHAAB заблокирована в таблице GAL.X$ACTIVEUSERS. Чтобы найти, кто из подключенных пользователей заблокировал эту строку, я написал и выполнил следующий запрос:

SELECT GAL.INTTOHEX (ss.SID, 4) || GAL.INTTOHEX (ss.SERIAL#, 4)
          L_SESS,
       ss.SID,
       ss.SERIAL#,
       ss.USERNAME,
       loc.ADDRESS
  FROM V$SESSION ss, GAL.SYS#LOCKS loc
 WHERE     STATUS <> 'KILLED'
       AND loc.dbsessionid =
                 GAL.INTTOHEX(ss.SID, 4)
              || GAL.INTTOHEX(ss.SERIAL#, 4)
       AND loc.address = 'AAALsvAAFAAAACHAAB';

Определив Sid и Serial# блокирующей сессии по результатам запроса, я смог убить эту сессию, чтобы строка AAALsvAAFAAAACHAAB стала достуной.

ALTER SYSTEM KILL SESSION 'sid, Serial#' IMMEDIATE;

После того, как сессия была убита, новые пользовательские сессии к ERP Галактика стали устанавливаться.

Remove Listener.log without restart Oracle Listener service

  • Oracle on Windows

Иногда требуется удалить файл listener.log, который стал занимать много свободного места на диске, но при этом не останавливая службу Oracle Listener. Для этого имеется следующее решение:

1. Переходим в каталог с listener.log и запускаем консоль управления listener.

CMD>
CD c:\OracleDB11_R2\11.2.0\diag\tnslsnr\srv01test\test01listener\trace\
LSNRCTL

2. В консоли LSNRCTL делаем текущим listener, для которого будем удалять файл-лог, и выполняем команду отключения логирования.

LSNRCTL>
set current_listener test01listener
set log_status off
exit

3. Удаляем физически файл-лог.

CMD>
del test01listener.log

4. Затем в консоли LSNRCTL включаем логирование listener.

LSNRCTL>
set current_listener test01listener
set log_status on
exit

5. Слушатель (Listener) начнет запись в новый файл-лог.

Upload/import DBASE/FoxPro DBF files into Oracle Database

Simply Notes

If you need to import/upload data from DBF (DBASE or Foxpro database files), there is a script that already developed by Tom Kyte.

I have made some modification to fulfill my need, here are the changes:

  • Add UPLOAD_TIME column to keep date of upload process from DBF into oracle
  • Add support of MEMO fields that has more than 4000 characters

Howto use this script?

First you need to prepare Oracle directory where the dbf files will you stored
You can called it to any name you like. For my example i choose to named it as DIRDBF.

Show structure table of employee.DBF that located on DIRDBF directory
This will also generate Oracle’s command of «create table » which constructed from DBF structure format. This table should be exists in Oracle database before import/upload process in next step.

Uplad employee.DBF that located on DIRDBF directory into Oracle database
This is simple…

View original post ещё 48 слов

Distributed transaction and ORA-01591: lock held by in-doubt distributed transaction

Иногда при работе с удаленной базой non-Oracle по средствам Heterogenous service (HSODBC) или Oracle GateWay (DG4MSQL) может возникнуть ситуация, когда во время распределенной транзакции происходит сбой (при DML-операциях) и транзакция зависает, что может вызвать эксклюзивные блокировки некоторых объектов или вообще заблокировать доступ к удаленной базе.
Чтобы разрешить эту ситуацию нужно выполнить следующие шаги:

1. Проверяем alert_<your_dbname>.log на ошибки связанные с распределенными транзакциями или смотрим на всплывающую ошибку при работе с удаленной базой. Например, ORA-01591: lock held by in-doubt distributed transaction 9.3.919809,
где 9.3.919809 — это ID транзакции, которая вызывает ошибку.

2. Проверяем в каком состоянии (State) находится транзакция:

SELECT LOCAL_TRAN_ID,
STATE,
FAIL_TIME,
TOP_OS_USER,
TOP_OS_TERMINAL
FROM SYS.PENDING_TRANS$
WHERE LOCAL_TRAN_ID = '9.3.919809';

LOCAL_TRAN_ID   STATE       FAIL_TIME              TOP_OS_USER      TOP_OS_TERMINAL
---             ---         ---                    ---              ---
9.3.919809      prepared    12.05.2014 14:55:00    ITWARE\ITUSER    IT03

LOCAL_TRAN_ID - ID транзакции
STATE - состояние транзакции (особое внимание!)
FAIL_TIME - время сбоя
TOP_OS_USER - имя пользователя ОС
TOP_OS_TERMINAL - имя компьютера пользователя

3. Определив состоянии зависшей транзакции, можем перейти к таблице 1, где описаны варианты решения проблем при помощи пакета DBMS_TRANSACTION (состояние транзакции в поле State Column):

STATE Column

State of Global Transaction

State of Local Transaction

Normal Action

     Alternative Action

Collecting Rolled back Rolled back None PURGE_LOST_DB_ENTRY(only if autorecovery cannot resolve transaction)
Committed Committed Committed None PURGE_LOST_DB_ENTRY(only if autorecovery cannot resolve transaction)
Prepared Unknown Prepared None Force commit or rollback
Forced commit Unknown Committed None PURGE_LOST_DB_ENTRY(only if autorecovery cannot resolve transaction)
Forced rollback Unknown Rolled back None PURGE_LOST_DB_ENTRY(only if autorecovery cannot resolve transaction)
Forced commit Mixed Committed Manually remove  inconsistencies then use PURGE_MIXED
Forced rollback Mixed Rolled back Manually remove inconsistencies then use PURGE_MIXED

Пример
После того, как произошел сбой при обновлении данных в одной из таблиц удаленной базы (MS SQL) через интерфейс Oracle DG4MSQL, дальнейшее подключение к этой базе из Oracle стало невозможным. Процесс DG4MSQL.exe отключен, сессия пользователя отключена, но зависшая транзакция не завершилась (не откатилась).
Выполнив п.1 — 3, описанные выше, определил, что зависшая распределенная транзакция 9.3.919809 находится в состоянии prepared. По таблице 1 в качестве альтернативы решения, предлагается выполнить commit force или rollback force.
Я использовал:

commit force '9.3.919809';

Затем проверил вновь состояние транзакции, оно изменилось на forced commit. По таблице 1 предлагается удалить транзакцию при помощи процедуры DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY:

EXEC DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('9.3.919809');

После выполнения данной процедуры, транзакция была успешно удалена, и она исчезла из зависших (запрос п.2 ничего не вернул по ней). После чего подключение к удаленной базе было восстановлено.

Дополнительно:

http://docs.oracle.com/cd/B28359_01/server.111/b28310/ds_txns001.htm#ADMIN12211
http://www.dba-oracle.com/t_two_phase_commit_2pc.htm
http://docs.oracle.com/cd/B28359_01/server.111/b28310/ds_txnman006.htm#ADMIN12266
http://blog.itpub.net/38267/viewspace-713103
https://blogs.oracle.com/db/entry/oracle_support_master_note_for_troubleshooting_managed_distributed_transactions_doc_id_1006641

Как получить инициалы (INITIALS) из ФИО (NAME)

  • Oracle 10, 11

Данная конструкция позволяет из ФИО (NAME) сотрудника получить фамилию (LASTNAME), имя (FIRSTNAME), отчество (FATHERNAME) и иницалы (INITIALS).

with t as
(select 'Иванов Петр Васильевич' as name from dual)
select t.name,
regexp_replace(t.name, ' (.*)') LASTNAME,
regexp_replace(t.name, ' (.*)|^[^ ]* ') FIRSTNAME,
regexp_replace(t.name, '(.*) ') FATHERNAME,
regexp_replace(regexp_replace(t.name, ' (.*)|^[^ ]* '),'.*','.',2,1)||regexp_replace(regexp_replace(t.name, '(.*) '),'.*','.',2,1) INITIALS
from t;

NAME                    LASTNAME  FIRSTNAME  FATHERNAME  INITIALS
----------------------  ------    ----       ----------  ----                                                            
Иванов Петр Васильевич  Иванов    Петр       Васильевич  П.В.