среда, 2 июня 2010 г.

ORA_DATABASE_NAME

Что должен возвращать следующий запрос?
SQL> SELECT ora_database_name FROM dual
Первое что приходит на ум, результатом выполнения этого запроса должно быть имя текущей базы данных. Но действительно ли всё это так просто, как кажется на самом деле? Попробуем разобраться, что же представляет на самом деле эта функция, каков её источник и как можно изменить результат, выводимый этой функцией.

Прежде чем приступить к непосредственному практическому изучению ora_database_name, вспомним, как трактуется она в документации Oracle. Единственное упоминание о ней мы найдем только в книге Oracle Database Application Developer's Guide - Fundamentals в разделе Coding Triggers, где описывается, что она принадлежит к группе функций для идентификации атрибутов происшедшего события.  Таких разнообразных функций  на самом деле около тридцати, они все начинаются с префикса ora_ и используются в основном в системных триггерах. Судя по документации, наша функция ora_database_name должна выводить имя базы данных. Проверим, действительно ли это так:
SQL> SELECT ora_database_name FROM dual
 
ORA_DATABASE_NAME                   
------------------------------------
ORCL.REGRESS.RDBMS.DEV.US.ORACLE.COM

Как видим, запрос возвращает склейку локального имени базы данных и доменного имени сетевой структуры, то есть глобальное имя базы данных. Посмотреть локальную составляющую можно с помощью следующего запроса:
SQL> SELECT name FROM v$database
 
NAME
----
ORCL

А вот просмотр доменной вызовет трудности. По идее эти части должны определяться на уровне создания инициализационными параметрами базы данных db_name и db_domain. Посмотрим их значения:
SQL> SHOW PARAMETERS db_name
 
Параметр Тип    Значение
-------- ------ --------
db_name  string orcl    
 
SQL> SHOW PARAMETERS db_domain
 
Параметр  Тип    Значение
--------- ------ --------
db_domain string         

Если с параметром db_name всё понятно, то параметр db_domain ничего не содержит. Откуда же тогда взялась эта вторая часть глобального имени?  Скорее всего, это значение по умолчанию, так как db_domain до создания базы имел значение NULL.  Теперь изменение вышеприведенных параметров ни как не повлияет на состав глобального имени. Если изменить первый параметр, база просто не откроется, а изменение значения второго параметра будет просто проигнорировано.
Ясно, что хоть эти параметры и участвуют в организации глобального имени на этапе создания базы данных, но они не являются источником для функции, которую мы рассматриваем. На самом деле ora_database_name это всего лишь публичный синоним, указывающий на функцию database_name, которая в свою очередь состоит из единственного вызова одноимённой функции  database_name пакета dbms_standard. В свою очередь функция пакета, использует внешнюю С функцию.
Казалось, след потерян, доступа к функции нет. Но не всё так плохо. Есть одно системное представление global_name, содержимое которого идентично результату выполненного ранее нами запроса. Может оно приведёт нас к источнику нашей функции:
SQL> SELECT * FROM global_name
 
GLOBAL_NAME                         
------------------------------------
ORCL.REGRESS.RDBMS.DEV.US.ORACLE.COM      

Данное представление ссылается на строку с именем GLOBAL_DB_NAME  в таблице props$ схемы sys. Эта таблица относится к словарю и содержит некоторые значения фиксированных параметров базы данных. Попробуем изменить это параметр прямо в таблице и посмотреть, изменится ли значение возвращаемое функцией ora_database_name:
SQL> UPDATE global_name SET global_name = 'ORCL2';
 
Изменено: 1 строка

SQL> COMMIT;
 
Commit complete

SQL> SELECT ora_database_name FROM dual
 
ORA_DATABASE_NAME                   
------------------------------------
ORCL.REGRESS.RDBMS.DEV.US.ORACLE.COM

Выводимый результат функции не изменился. Он измениться только после перезагрузки экземпляра. Но уже сейчас ясно, что строка GLOBAL_DB_NAME  таблицы props$ не связана напрямую с результатом, который выводит функция ora_database_name.
И так, похоже, мы нашли способ, который изменит выводимое значение глобального имени. Но правка системной таблицы Oracle не самый лучший вариант. К счастью в Oracle есть команда  ALTER DATABASE RENAME GLOBAL_NAME, которая предназначена для изменения глобального имени базы данных. Попробуем с её помощью изменить наше глобальное имя:
SQL> ALTER DATABASE RENAME GLOBAL_NAME TO ORCL3;
 
База данных изменена

SQL> SELECT ora_database_name FROM dual;
 
ORA_DATABASE_NAME
-----------------
ORCL3            

Как видим, функция ora_database_name стала сразу выдавать необходимый нам результат, при этом нам не понадобилось даже перезагружать экземпляр. Правда в этом способе изменения глобального имени есть небольшая оговорка. Например, если у предыдущего имени есть доменная составляющая, то отбросить её с помощью ALTER DATABASE в новом имени уже не получиться:
SQL> ALTER DATABASE RENAME GLOBAL_NAME TO ORCL.REGRESS.RDBMS.DEV.US.ORACLE.COM;
 
База данных изменена

SQL> SELECT ora_database_name FROM dual;
 
ORA_DATABASE_NAME                   
------------------------------------
ORCL.REGRESS.RDBMS.DEV.US.ORACLE.COM
 
Выбрано: 1 строка

SQL> ALTER DATABASE RENAME GLOBAL_NAME TO ORCL1;
 
База данных изменена

SQL> SELECT ora_database_name FROM dual;
 
ORA_DATABASE_NAME                    
-------------------------------------
ORCL1.REGRESS.RDBMS.DEV.US.ORACLE.COM

Выбрано: 1 строка

Придётся комбинировать эти два способа:
SQL> UPDATE global_name SET global_name = 'ORCL2';
 
Изменено: 1 строка

SQL> COMMIT;
 
Commit complete

SQL> ALTER DATABASE RENAME GLOBAL_NAME TO ORCL2;
 
База данных изменена

SQL> SELECT ora_database_name FROM dual;
 
ORA_DATABASE_NAME
-----------------
ORCL2            

Выбрано: 1 строка

В заключение стоить отметить, что изменение вышеописанными способами глобального имени никаким образом не скажется на локальном имени базы данных. Выполним, к примеру, после всех изменений следующий запрос:
SQL> SELECT name FROM v$database
 
NAME
----
ORCL

Локальное имя базы данных осталось прежним. Отсюда следует помнить, что локальная составляющая глобального имени должна всегда соответствовать локальному имени базы данных. Это следует учитывать при изменении глобального имени.
И так, результат достигнут. Мы узнали, что собой представляет функция ora_database_name и как можно изменить возвращаемое ею содержимое.  Теперь можно сделать и выводы:
  1. Функция ora_database_name возвращает глобальное имя базы данных, состоящее из локальной составляющей и доменного имени сетевой инфраструктуры.
  2. Значение, возвращаемое функцией связанно с параметрами db_name и db_domain только на этапе создания базы данных. Их изменение в дальнейшем никак не повлияет на выводимый результат.
  3. Локальная составляющая выводимого значения (глобального имени) может отличаться от локального имени базы данных, но лучше этого не делать.
  4. Выводимое значение идентично фиксированному параметру GLOBAL_DB_NAME базы данных, значение которого храниться в таблице props$ схемы sys. Изменение этого значения оказывает влияние на выводимый результат, но только после перезагрузки экземпляра.
  5. Выводимое значение (глобальное имя) можно изменить с помощью команды ALTER DATABASE RENAME GLOBAL_NAME, при этом перезагрузка экземпляра не требуется. Команда никогда не откидывает доменную составляющую глобального имени. Для этого надо вручную изменять строку параметра GLOBAL_DB_NAME в таблице props$.

Комментариев нет: