Ноябрь/Декабрь 2001

Советы, рекомендации, опыт


Использование Oracle Provider for OLEDB

Игорь Мельников,
mailto:Igor Melnikov
компания TopS BI,
Москва

Интеграция СУБД Oracle и продуктов Microsoft

Данная статья предназначена для программистов, разрабатывающих Intranet/Internet приложения для СУБД Oracle, а также для администраторов (DBA) Oracle for Windows NT/2000. В ней рассматриваются вопросы создания internet-сайтов на основе web-сервера Microsoft Internet Information Server (IIS) и технологий Active Server Pages [ASP] и Windows Scripting Host [WSH], где в качестве сервера баз данных используется Oracle.

Использование IIS - это лишь один из примеров использования Oracle OLE DB, поскольку общая методология работы в других продуктах MS остаетcя без изменений. В IIS используется объектная модель ASP, в MS Exchange 2000 - объектная модель Exchange; если вы программируете в MS Excel 2000, вы будете использовать Visual Basic for Application [VBA] и объектную модель Excel, и так далее. Вообще говоря, создавать приложения, работающие с ADO DB/OLE DB, может любое средство разработки, которое поддерживает позднее связывание COM-объектов (через реализация dispatch-интерфейса), например: Borland Delphi или MS Visual Basic.

Разумеется, данный обзор не претендует на полноту изложения всех возможностей данных продуктов - всех интересующихся отсылаю к документации поставляемой компаниями Oraсle и Microsoft.

Краткий экскурс в технологию доступа к данным Microsoft ActiveX Data Objects (ADO).

Объекты ADO (ActiveX Data Objects - Объекты данных ActiveX) представляют собой автоматизированный интерфейс доступа к данным. Доступ к многочисленным источникам данных, включая и ODBC, осуществляется посредством интерфейса OLE DB. ADO является интерфейсом программного уровня к OLE DB, и мощной парадигме доступа к данным от Microsoft. OLE DB обеспечивает доступ ко многим источникам данных. ADO DB и OLE DB вместе представляют собой основу стратегии Универсального доступа к данным (Universal Data Access). OLE DB дает возможность универсального доступа ко многим данным и представляет разработчикам возможность сделать это достаточно легко. Так как ADO находится на вершине OLE DB, то применение ADO имеет все преимущества Универсального доступа к данным, которое обеспечивает OLE DB.
Для работы с OLE DB необходим промежуточный слой, который обеспечивает трансляцию высокоуровневых вызовов в низкоуровневые вызовы API конкретного источника данных - данное программное обеспечение получило название провайдера OLE DB (Provider for OLE DB). Использовать ADO DB можно всех продуктах MS поддерживающих OLE-автоматизацию с помощью скриптовых движков. Посредством универсального механизма доступа к данным OLE DB/ADO DB возможна интеграция с системами электронной почты на базе MS Exchange 2000 (например с использованием Routing Scripting Agent), с веб-серверами MS Internet Information Server (на основе технологии Active Server Pages), продуктами семейства MS Office (с помощью Visual Basic for Application), Windows Scripting Host (используя MS Script Engine),MS SQL Server 2000 (c использованием Data Transformation Wizard).


Рис. 1 - Использование ADO DB

Описание Oracle Provider for OLE DB

Oracle Provider for OLE DB представляет собой программное обеспечение промежуточного слоя, которое производит трансляцию вызовов OLE DB в вызовы OCI. Разумеется для его работы необходимо наличие установленного клиента Oracle (Oracle Client). Насколько мне известно, начиная с версии 8.1.5, Oracle OLE DB Provider входит в поставку клиентского программного обеспечения Oracle для Windows (Oracle Client for Windows NT/2000). Тем не менее последняя версия Provider for OLE DB может быть загружена с сайта OTN в виде отдельного продукта.
Помимо обазательных стандартных для OLE DB интерфейсов, свойств м методов, данный продукт обеспечивает ряд дополнительных возможностей которые специфичны именно для СУБД Oracle: работа с хранимыми процедурами возвращающими ссылку на курсор (ref cursor), работа с BLOB-полями (CLOB,BFILE), поддержка типов данных БД, поддержка распределенных транзакций и т.д.

Проектирование Web-страниц для отображения данных СУБД Oracle c использованием технологии Active Server Pages (ASP) и Oracle provider for OLEDB.

Одним из наиболее распостраненных примеров использования ADO DB является написание активных серверных скриптов (ASP) компании Microsoft. ASP скрипты служат для формирования динамических страниц HTML. Интерпретирует ASP страницы Web-сервер MS Internet Information Server. В качестве языков программирования ASP-скриптов используются языки JavaScript и VBscript. Интерпретаторы с этих языков присутствуют в поставе опереционных систем Windows 2000. На данный момент мне известны два других интерпретатора разработанных сторонней фирмой: это Perl и Python фирмы ActiveState (http://www.activestate.com/). Но поскольку интерпретаторы языков VBScript и JavaScript имеются в поставке WIndows NT/2000, в примерах я буду использовать именно эти языки.

Соединение с СУБД Oracle.
Для соединения с экземпляром Oracle предназначен компонент ADODB.Connection. Для создания сессии необходимо указать в свойстве ConnectionString на использование в качестве провайдера Oracle OLEDB.
Пример на языке JavaScript:

   <%
    var xConn = new ActiveXObject("ADODB.Connection");
    xConn.Open("Provider=OraOLEDB.Oracle;User ID=scott;Password=tiger;Data Source=test;PLSQLRSet=1;");
    try
     {     
      // ...
      // вставьте ваш код здесь ...
      // ...
     }
    finally
     {
      xConn.Close();
     }
    delete xConn;

   %>
   
Пример на языке VBScript:
    <%
    Dim xConn
    Set xConn = CreateObject("ADODB.Connection")
    xConn.Open "Provider=OraOLEDB.Oracle;User ID=scott;Password=tiger;Data Source=igorm;PLSQLRSet=1;"
    ' ...
    ' вставьте ваш код здесь
    ' ...
    xConn.Close
    Set xConn = Nothing
    %>
   
В приведенном выше примере первые два параметра являются обычными для соединений с БД и поэтому не вызывают вопросов - это имя пользователя и его пароль. Значение третьего параметра (Data Source) представляет собой имя алиаса (так называемый host-name) сервера Oracle который предварительно был определен с помощью утилиты Net8 Configuration Assistant. Последний параметр (PLSQLRSet) требует пояснений. Данный параметр является особенностью Oracle OLE DB. Он управляет возможностью получения наборов данных (RecordSet) через указатели на курсор (ref cursor), получаемые в ADO как выходные параметры хранимых функций и процедур. Также обратите внимание на использование секции finally в примере на языке JavaScript, для гарантированного закрытия соединения с БД в случае возникновения исключительной ситуации.

Выборка данных.
Для выборки данных предназначен компонент ADODB.RecordSet. Для открытия курсора необходимо вызвать его метод Open .Перед его использованием необходимо определить свойство ActiveConnection, присвоив ему предварительно проинициированный объект ADODB.Connection. Для перехода к следующей записи курсора предназначен метод MoveNext,чтобы определить признак конца курсора нужно опросить свойство EOF.
Пример на языке JavaScript:

   <%
    var xConn = new ActiveXObject("ADODB.Connection");
    xConn.Open("Provider=OraOLEDB.Oracle;User ID=scott;Password=tiger;Data Source=test;PLSQLRSet=1;");
    var xRS = new ActiveXObject("ADODB.RecordSet");
    xRS.ActiveConnection = xConn;
    xRS.Open('select * from employes');
    while (!xRS.EOF)
     {
      Response.Write('<p>' + '</p>\r\n');
      Response.Write('<hr>\r\n');
      xRS.MoveNext();
     }

    xRS.Close();

    // ...
    // insert you code here ...    
    // ...
    xConn.Close();

    delete xConn;
   %>
   
Пример на языке VBScript:
    <%
    Dim xConn
    Set xConn = CreateObject("ADODB.Connection")
    xConn.Open "Provider=OraOLEDB.Oracle;User ID=scott;Password=tiger;Data Source=igorm;PLSQLRSet=1;"
    ' ...
    ' insert you code here ...    
    ' ...
    xConn.Close
    Set xConn = Nothing
    %>
   

Выполнение хранимых процедур и функций СУБД Oracle.
Важнейней составной частью развитых информационных систем на базе Oracle являются хранимые процедуры и функции. Для их использования предназначен компонент ADODB.Command. Аналогично компоненту ADODB.RecordSet он имеет свойство ActiveConnection, которое неоходимо определить до вызова хранимой процедуры.
Пример на JavaScript:

    <%
    var xCommandFunc = new ActiveXObject("ADODB.Command");
    xCommandFunc.ActiveConnection = xConn;

    xCommandFunc.Parameters.Append(xCommandFunc.CreateParameter("RES",8,2,250));
    xCommandFunc.CommandText = "BEGIN :RES := OLEDB_TEST1.HELLO; END;";

    xCommandFunc.Execute();
    Response.Write('<p>' + xCommandFunc.Parameters("res").Value + '</p>\r\n');
    delete xCommandFunc;
    %>
   
В вышеописанном примере происходит вызов пакетированной хранимой функции HELLO определенной в пакете OLEDB_TEST1. Для получения результата выполнения данной функции используется host-переменная RES Пример выполнения хранимой процедуры на языке JavaScript:
    <%
    //--- example of use procedure with parameters:
    var xCommandProc = new ActiveXObject("ADODB.Command");
    xCommandProc.ActiveConnection = xConn;
    
    xCommandProc.CommandText = "OLEDB_TEST1.proc_test";
    xCommandProc.CommandType = 4;
    xCommandProc.Parameters.Append(xCommandProc.CreateParameter("param1",3,3));
    xCommandProc.Parameters.Append(xCommandProc.CreateParameter("param2",8,2,250));
    
    xCommandProc.Parameters("param1").Value = 1;
    xCommandProc.Parameters("param2").Value = "text value";
    
    xCommandProc.Execute();

    Response.Write(xCommandProc.Parameters("param2").Value);
    %>
   
Пример на VBScript:
    <%
    '--- example of use procedure with parameters:
    Dim xCommandProc = CreateObject("ADODB.Command")

    xCommandProc.ActiveConnection = xConn
    
    xCommandProc.CommandText = "OLEDB_TEST1.proc_test"
    xCommandProc.CommandType = 4
    xCommandProc.Parameters.Append(xCommandProc.CreateParameter("param1",3,3))
    xCommandProc.Parameters.Append(xCommandProc.CreateParameter("param2",8,2,250))
    
    xCommandProc.Parameters("param1").Value = 1
    xCommandProc.Parameters("param2").Value = "text value"
    
    xCommandProc.Execute

    Response.Write(xCommandProc.Parameters("param2").Value)
    %>
   
Здесь процедура PROC_TEST входит в состав пакета OLEDB_TEST1. Данная процедура имеет два входных параметра: param1 - типа NUMBER, и param2 - типа VARCHAR2. Описание числовых констант, используемых в вачестве параметров вызов метода CreateParameter находиться в документации по ADODB.

Использование операторов Insert,Update,Delete.
Для выполнения данных команд предназначен компонент ADODB.Command. В отличие от предыдущего раздела (использование хранимых процедур): нужно лишь установить другое значение свойства CommandType данного компонента:

   <%
    //Пример на JavaScript
    var xCommandProc = new ActiveXObject("ADODB.Command");
    xCommandProc.ActiveConnection = xConn;
    xCommandProc.CommandType      = 8;
    xCommandProc.CommandText      = "insert into emp " +
                " values (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20)";
   %>
   
Свойству CommandText объекта ADODB.Command необходимо присвоить тесктовую строку, содержащую соответствующий SQL-оператор.

Использование технологии Windows Scripting Host (WSH) и Oracle provider for OLEDB для решения административных задач.
Другим полезным применением OLE DB Provider служит технология Windows Scripting Host [WHS]. Технология WSH пришла на смену архаичным командым файлам (bat-файлам), хорошо известным по среде DOS. Используя WSH программист имеет доступ к ADODB-объектам автоматизации, а также к объектной модели Windows. Хорошим применением OLE DB в данном случае будет решение с помощью скриптов WSH административных задач. В следующем листинге приведен пример такого использования для выполнения "холодного" копирования БД.

           //JavaScript language
       
           //Oracle settings:
           
           gOracleSID = 'igorm';
           gOracleUsername    = 'system';
           gOraclePassword    = 'manager';
           ServiceTimeOut     = 120;

           //Список control-файлов
           var gControlFiles = new Array();
           
           //Список файлов данных
           var gDataFiles = new Array();
           
           //Список online-логов
           var gOnlineLogFiles = new Array();
           
           //Куда копируем:
           gRootDir         = 'c:\\BackUp\\Oracle';
           gControlFilesDir = 'ControlFiles';
           gDataFilesDir    = 'DataFiles';
           gOnlineLogFilesDir = 'OnlineLogFiles';

           gInitOraFilesDir = 'InitOraFiles';
           
           function CopyFiles(pFileList,pDestDir)
            {
             for (var i in pFileList)
              {
               f = xfso.GetFile(pFileList[i]);
               f.Copy(gRootDir + '\\' + pDestDir + '\\'+ f.Name,true);
               WScript.StdOut.WriteLine('File "' + gRootDir + '\\' + pDestDir + '\\' + f.Name +
                                        '" succesfully copied');
              }
            }
           
           var WshShell = new ActiveXObject("WScript.Shell");
           
           var xConn = new ActiveXObject("ADODB.Connection");
           xConn.Open("Provider=OraOLEDB.Oracle;User ID=" + gOracleUsername +
                       ";Password=" + gOraclePassword + ";");
           
           var xRS = new ActiveXObject('ADODB.RecordSet');
           xRS.ActiveConnection = xConn;
           
           //получаем список control-файлов:
           xRS.Open('select name from v$controlfile');
           while (!xRS.EOF)
            {

             gControlFiles[gControlFiles.length] = xRS.Fields('name').Value;
             xRS.MoveNext();
            }
           xRS.Close();
           
           //получаем список файлов данных:
           xRS.Open('select name from v$datafile');
           while (!xRS.EOF)
            {
             gDataFiles[gDataFiles.length] = xRS.Fields('name').Value;
             xRS.MoveNext();
            }
           xRS.Close();
           
           //получаем список файлов данных:
           xRS.Open('select member from v$logfile');
           while (!xRS.EOF)
            {
             gOnlineLogFiles[gOnlineLogFiles.length] = xRS.Fields('member').Value;
             xRS.MoveNext();
            }
           xRS.Close();
           
           xConn.Close();
           
           //Останавливаем инстанцию
           WScript.StdOut.WriteLine('Останавливаем инстанцию...');

           WshShell.Run("oradim -shutdown -sid " + gOracleSID + " -shuttype srvc,inst -shutmode i",
                        0,
                        true);
           
           WScript.StdOut.WriteLine('Делаем холодную копию...');
           var xfso = new ActiveXObject("Scripting.FileSystemObject");
           
           //Control-files:
           CopyFiles(gControlFiles,gControlFilesDir);
           
           //Data-files:
           CopyFiles(gDataFiles,gDataFilesDir);
           
           //Online logs:
           CopyFiles(gOnlineLogFiles,gOnlineLogFilesDir);
           
           //Запускаем инстанцию:
           WScript.StdOut.WriteLine('Запускаем инстанцию...');
           WshShell.Run("oradim -startup -sid " + gOracleSID,
                        0,
                        true);
           
              

Литература:

  • Oracle в Provider for OLE DB Developer's Guide, Release 9.0.1 for Windows June 2001 Part No. A90171-01
  • Microsoft Platfom SDK, July 2000
  • E-mail this page