Перейти к тексту

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Вся введенная информация защищена.

  • Закрыть [x]

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Вся введенная информация защищена.

  • Закрыть [x]

Применение хранимых процедур Common SQL API продукта DB2 for z/OS в инструментальных приложениях

Использование технологии Java в качестве интерфейса к хранимым процедурам Common SQL API продукта DB2

Кнут Стольц, разработчик утилит DB2 z/OS, IBM
Кнут Стольц (Knut Stolze) начал работать с DB2, когда в 1999 году он присоединился к IBM в качестве временного научного сотрудника в Silicon Valley Lab, США, где он работал над DB2 Image Extender. Он перешел в команду разработчиков DB2 Spatial Extender и был ответственным за совершенствование удобства использования и производительности данного продукта, а также за обеспечение его соответствия стандартам. В период с 2002 по 2006 год Кнут был студентом отделения философии и помощником преподавателя в Университете г. Йена, Германия. В то же время он продолжал работать в IBM, участвуя в разработке Information Integrator. Сегодня Кнут входит в команду разработчиков, отвечающую за функционал Admin Enablement в DB2 for z/OS. С ним можно связаться через новостные группы newsgroups comp.databases.ibm-db2 и ibm.software.db2.udb.spatial или через электронную почту stolze@de.ibm.com.
Марсель Кутш, разработчик DB2 for z/OS, IBM  
Марсель Кутш (Marcel Kutsch) является инженером по программному обеспечению в лаборатории IBM в Бёблингене (Германия). В настоящее время он занимается проектированием и созданием хранимых процедур, а также одного из компонентов DB2 for z/OS – планировщика административных задач. До прихода в IBM в качестве постоянного сотрудника М. Кутш работал в качестве стажера в Исследовательском центре IBM Almaden, где занимался оптимизацией запросов для продукта DB2 for Linux, UNIX и Windows. Его первой областью деятельности в IBM после окончания университета в 2005 г. были функции автономной работы продукта DB2.

Описание:  В статье подробно описывается применение набора хранимых процедур Common SQL API (CSA), которые имеются для всех серверов данных IBM®. Приводятся сведения по использованию процедур Common SQL API и их интеграции в приложение. В статье рассматривается небольшое Web-приложение J2EE на базе Common SQL API, которое сравнивает параметры подсистем в двух экземплярах IBM DB2® for z/OS®, используя для этого хранимую процедуру GET_CONFIG CSA.

Дата:  25.12.2009
Уровень сложности:  средний PDF:  A4 and Letter (213KB | 19 страница)Загрузить Adobe® Reader®
Активность:  3469 просмотров
Комментарии:  


Введение

Системы управления базами данных IBM, такие как DB2 for z/OS, IBM DB2 for Linux®, UNIX® and Windows® и IBM Informix® Dynamic Server (IDS), поставляются с большим количеством разнообразных административных функций и процедур. С одной стороны, эти процедуры облегчают доступ к административной информации сервера данных для приложений и инструментов дистанционно расположенной базы данных, с другой стороны, они тесно связывают приложение с подключенным к нему сервером данных. Это обуславливается главным образом такими факторами, как различия в синтаксисе, опциях безопасности и методах доступа, которые имеют место между разными серверами данных, а иногда даже между разными версиями одного и того же сервера данных. Как результат, эти приложения и инструменты страдают от таких недостатков, как более высокая сложность реализации, медленная интеграция и трудности повторного использования. В данной статье описывается несколько методов работы с процедурами Common SQL API – набором хранимых процедур, который реализован для всех серверов данных IBM и позволяет решать вышеупомянутые проблемы.


Введение в Common SQL API

Common SQL API – это набор процедур, каждая из которых имеет одинаковую сигнатуру на всех серверах данных IBM. Использование XML-документа в качестве входных и выходных параметров дополнительно повышает стабильность сигнатур этих процедур между различными версиями. Поскольку одинаковые методы вызова и соображения безопасности могут быть применены для всех серверов данных IBM и даже для нескольких версий одного сервера данных, вызывающему эти процедуры прикладному коду нет необходимости знать о конкретной версии сервера данных. Это упрощает код и существенно облегчает интеграцию приложений.

На данный момент набор Common SQL API для версий 8 и 9 продукта DB2 for z/OS состоит из трех хранимых процедур, которые применяются преимущественно для сбора информации о конфигурации сервера данных, а также данных об использовании ресурсов.


Таблица 1. Хранимые процедуры Common SQL API
Имя хранимой процедуры Выполняемые функции
SYSPROC.GET_MESSAGEВозвращает короткий текст сообщения, ассоциированного с предоставленной переменной SQLCODE
SYSPROC.GET_SYSTEM_INFOВозвращает следующую информацию о конфигурации системы
  • Информация об операционной системе
    • Название и выпуск
    • Модель центрального процессора, количество подключенных процессоров, идентификатор процессора, серийные номера подключенных процессоров
    • Реальный размер устройств хранения
  • Информация о продукте
    • Исходное JES-имя, выпуск, имя узла, выходной класс
    • Имя и FMID программных средств обеспечения безопасности
    • Выпуск DFSMS
    • Выпуск TSO
    • Выпуск VTAM
  • DB2 MEPL
  • Статус применения SYSMOD
  • Правила классификации WLM
SYSPROC.GET_CONFIGВозвращает следующую информацию о конфигурации сервера данных
  • Информация о группе совместного использования данных
    • Имя группы, уровень, режим, уровень протокола, имя подключения
    • Участник DB2, идентификатор подсистемы, префикс команды, статус, уровень
    • Имя системы z/OS, подсистема IRLM, процедура IRLM
    • Размер структуры SCA, статус, использование
    • Размер структуры LOCK1 и число элементов
    • Число элементов списка, использование
  • Параметры подсистемы DB2
    • Имя управляющего блока
    • Имя панели установки
    • Имя поля панели установки
    • Местоположение на панели установки
    • Имя параметра подсистемы
    • Значение параметра подсистемы
  • Информация о механизме распределения данных
    • Статус DDF
    • Имя местоположения, Lu-имя, родовое Lu-имя
    • IP-адрес, порт TCP/IP, порт повторной синхронизации
    • Домен SQL, домен повторной синхронизации
    • DT, CONDBAT, MDBAT, ADBAT, QUEDBAT, INADBAT, CONQUED, DSCDBAT, INACONN
  • Подключенная подсистема DB2
  • Имена таблиц с лимитами активных ресурсов
  • Имена и тома активных наборов журнальных данных
  • Метка времени последнего перезапуска DB2


Каждая из перечисленных выше хранимых процедур собирает соответствующую информацию, представляет ее в виде XML-документа и возвращает его запрашивающему приложению или инструменту как выходной параметр типа BLOB. Этот XML-документ соответствует определению DTD (Document Type Definition), которое впервые появилось в продукте Apple Mac OS X (см. раздел Ресурсы). При использовании такого иерархического XML-списка свойств различия между платформами, технологиями и версиями выражаются посредством пар значений XML-ключа, поэтому нет необходимости в их представлении с помощью сигнатуры хранимой процедуры. Подробная информация по сигнатурам, функциям и XML-структурам списков свойств для набора Common SQL API содержится в главе 24 публикации серии IBM Redbooks под названием «DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond»: (см. раздел Ресурсы).


Онлайновый инструмент для сравнения параметров подсистем DB2 for z/OS

В оставшейся части данной статьи описывается Web-приложение J2EE, которое сравнивает параметры двух подсистем DB2 for z/OS (которые исполняются не в режиме совместного использования данных) и представляет результаты этого сравнения. Это Web-приложение использует хранимую процедуру Common SQL API с именем SYSPROC.GET_CONFIG, с помощью Java-сервлета анализирует раздел параметров подсистем в возвращенном выходном XML-документе, а затем выводит имя и значение параметра подсистемы с помощью JSP-страницы. На рисунке 1 показана главная панель описываемого Web-приложения. Имена параметров подсистем перечислены в первом столбце, а фактические значения каждого параметра для подсистемы V81A и подсистемы V81B перечислены во втором и третьем столбцах соответственно. Окрашивание строк в разные цвета имеет следующий смысл: зеленый цвет указывает на совпадение значений определенного параметра для обеих подсистем, красный цвет указывает на различие значений параметра в разных подсистемах, серым цветом окрашены строки для параметров, значения которых не могут быть сравнены, поскольку эти параметры не были установлены в одной из подсистем.


Рисунок 1. Главная выходная панель инструмента для сравнения параметров подсистем
Рисунок 1. Главная выходная панель инструмента для сравнения параметров подсистем


Значения параметров подсистем в главной панели Web-приложения представляют собой гиперссылки. Если пользователь нажмет указателем мыши на какое-либо значение в панели, приложение перейдет к соответствующему параметру подсистемы и отобразит более подробную информацию на новой странице. Пример такой информации для одного из параметров подсистем показан на рисунке 2:


Рисунок 2. Более подробное представление одного из параметров для двух подсистем
Рисунок 2. Более подробное представление одного из параметров для двух подсистем


Теперь, когда мы ознакомились с основными функциональными возможностями онлайнового инструмента для сравнения параметров подсистем DB2 z/OS, рассмотрим его практическую реализацию и сосредоточим свое внимание на обработке выходного XML-документа, возвращаемого хранимой процедурой GET_CONFIG. Ссылка на полный исходный код этого инструмента приведена в разделе Загрузка. Этот код имеет объем примерно 1000 строк и включает такие компоненты, как JSP-страницы, которые подробно не описываются в тексте статьи.

Реализация

Рассматриваемое Web-приложение основано на технологии J2EE и использует классический шаблон проектирования MVC (Model-View-Controller). Обработку исходного HTTP-запроса GEThttp://localhost:8080/ZpCompServlet?action=GETSUBSYSTEM осуществляет Java-сервлет, который выполняет функции компонента Controller – он управляет потоком прикладной программы на основе предоставленного параметра действия (action). Затем сервлет формирует объект Model (который по существу представляет собой набор всех параметров одной подсистемы DB2) и вставляет ссылку на него в объект HTTP-сессии. После настройки и инициализации компонента Model компонент Controller перенаправляет HTTP-запрос к компоненту View, который обращается к объекту Model и отображает параметры подсистемы в JSP-странице (Java Server Page). В листинге 1 показан фрагмент сервлета Controller. В соответствии с общепринятой практикой для реагирования на HTTP-запросы GET мы подменяем метод init() и метод doGet. Затем сервлет пытается получить объект HTTP-сессии, который впоследствии используется для хранения экземпляра компонента Model и для предоставления доступа к нему со стороны компонента View.


Листинг 1. Сервлет Controller — Часть 1
				
public class ZpCompServlet extends HttpServlet {

  private final String userID = "USERID";
  private final String password = "PASSWORD";

  /* Override init() method */
  public void init(ServletConfig conf) throws ServletException
  {
    super.init(conf);
  }

  /* Controller servlet */
  public void doGet(HttpServletRequest req, HttpServletResponse res)
                    throws ServletException, IOException {

  /* Obtain a new session */
  HttpSession session = req.getSession(true);
  PrintWriter out = res.getWriter();
  String action = req.getParameter("action");
  if (action.equals("GETSUBSYSTEM")) {
    /* create 2 worker subthreads */
    Thread[] threadpool = new Thread[2];
    SPWrapper[] spw = new SPWrapper[2];
    for (int i = 0; i < 2; i++) {
      spw[i] = new SPWrapper();
      /* Establish a connection */
      if (i % 2 == 0) {
         spw[i].establishCon("hostname:port/location-name ", userID, password);
       else
         spw[i].establishCon("hostname:port/location-name", userID, password);

      /* Init the parameters for a CSA call */
      spw[i].set_major(1);         // MAJOR_VERSION
      spw[i].set_minor(0);         // MINOR_VERSION
      spw[i].set_local("en_US");   // REQUESTED_LOCAL
      spw[i].set_xml_input(null);  // XML_INPUT
      spw[i].set_xml_filter(null); // XML_FILTER
      spw[i].set_SP_Name("GET_CONFIG");

      threadpool[i] = new Thread(spw[i]);
      threadpool[i].start();
    }
  }
            

Вызов хранимой процедуры

Web-приложение вызывает хранимую процедуру Common SQL API с именем SYSPROC.GET_CONFIG на двух подсистемах DB2. Приложение инициирует эти два вызова параллельно (другими словами, вы создаете два потока, каждый из которых подключается к одной из подсистем DB2). Затем каждый поток инициализирует входные параметры GET_CONFIG. Мы намереваемся вызвать процедуру GET_CONFIG в версии 1.0 («1» – максимальный основной номер версии, «0» – максимальный дополнительный номер версии, поддерживаемый на данный момент). Кроме того, необходимо вызвать локаль en_US. В версии 1.0 процедура GET_CONFIG не поддерживает формата XML для входных документов. Поэтому присваиваем этому входному параметру значение null. Мы не хотим фильтровать единственное значение ключа, поэтому не предоставляем и входного параметра для XML-фильтра. Используя указанные настройки, хранимая процедура конструирует полный выходной XML-документ, в одном из разделов которого перечислены все параметры подсистемы DB2. Обратите внимание, что для указания имени хранимой процедуры (процедуры GET_CONFIG) мы применяем setter-метод, поскольку те же самые значения параметров могут быть использованы для вызова других хранимых процедур Common SQL API (процедур SYSPROC.GET_SYSTEM_INFO).

Класс SPWrapper реализует функционирующий интерфейс для объекта потока. В этой точке мы создаем JDBC-соединение с сервером данных DB2 z/OS. В частности, функция establishCon использует JCC-драйвер com.ibm.db2.jcc.DB2Driver для установления соединения типа JDBC Type 4 с сервером данных, URL-адрес которого имеет вид jdbc:db2://hostname:port/location-name (см. листинг 2).


Листинг 2. Установление JDBC-соединения (SPWrapper)
				
public void establishCon(String url, String userID, String password) {
  try {
    Class.forName("com.ibm.db2.jcc.DB2Driver");
    con = DriverManager.getConnection("jdbc:db2://" + url, userID, password);
    con.setAutoCommit(false);
  }
  catch (ClassNotFoundException cnfe) {
    cnfe.printStackTrace();
  }
  catch (SQLException sqle) {
    System.out.println("Error during CALL " + " SQLSTATE = " + sqle.getSQLState() +
            " SQLCODE = "  + sqle.getErrorCode() + " : " + sqle.getMessage());
  }
}
            

Потоки, созданные в сервлете Controller, в конечном итоге вызывают хранимую процедуру. В функции callCSASP мы сначала готовим утверждение CALL для вызова хранимой процедуры, а затем связываем входные и выходные параметры с соответствующими маркерами параметра. Все XML-параметры, например, XML_INPUT и XML_OUTPUT, имеют тип BLOB. По этой причине мы не можем, например, просто связать строковые представления по маркеру параметра XML_FILTER. Сначала мы должны записать его в байтовый массив. В случае параметров типа BLOB нет необходимости в вызове приложения для выполнения каких-либо преобразований кодовой страницы (например, преобразований EBCDIC - UTF8 или UTF8 - EBCDIC для входных параметров). Хранимая процедура исходит из того, что входные XML-документы во входных BLOB-параметрах имеют кодировку UTF-8, и создает выходные XML-документы также в кодировке UTF-8. Как указывалось выше, тот же самый процесс может применяться для вызова любой другой хранимой процедуры из набора Common SQL API. В листинге 3 показано, как осуществляется вызов хранимой процедуры Common SQL API. Оценка возвращаемых параметров показана в сокращенном виде. Для ознакомления со всеми специфическими подробностями необходимо обратиться к исходному коду, ссылка на который приведена в разделе Загрузка.


Листинг 3. Настройка вызова процедуры (SPWrapper)
				
public void callCSASP() {
  try {
    // Prepare stored procedure CALL
    cstmt = con.prepareCall("CALL SYSPROC." + spName + "(?,?,?,?,?,?,?)");

    // Register input parameter
    cstmt.setInt(1, major_version);       // Major Version
    cstmt.setInt(2, minor_version);       // Minor Version
    cstmt.setString(3, requested_local);  // Requested Locale
    cstmt.setObject(4, xml_input, Types.BLOB);
    cstmt.setObject(5, xml_filter, Types.BLOB);

    // Output Parms
    cstmt.registerOutParameter(1, Types.INTEGER); // Major Version
    cstmt.registerOutParameter(2, Types.INTEGER); // Minor Version
    cstmt.registerOutParameter(6, Types.BLOB);    // XML_OUTPUT
    cstmt.registerOutParameter(7, Types.BLOB);    // XML_MESSAGE

    // Execute statement and commit
    cstmt.execute();
    con.commit();

    ctstmt_warning = cstmt.getWarnings();
    if (ctstmt_warning != null) {
      System.out.println("SQL Warning: " + ctstmt_warning.getMessage());
    }
    System.out.println("Major Version returned " + cstmt.getInt(1) );
    System.out.println("Minor Version returned " + cstmt.getInt(2) );

    ...

Выходные параметры XML_OUTPUT и XML_MESSAGE являются взаимно исключающими. Другими словами, если хранимая процедура выполнилась успешно, ее выходной XML-документ содержит всю информацию о конфигурации сервера данных, а сама эта процедура не возвращает никаких XML-документов с сообщениями. В данном случае мы извлекаем возвращенный BLOB-параметр XML_OUTPUT и продолжаем обработку этого объекта. В случае, если в процедуре произошла внутренняя ошибка, эта процедура возвращает XML-документ с сообщением, содержащим необходимые сведения об ошибке. При этом параметр XML_OUTPUT не возвращается. Если происходит подобная ошибка, вам достаточно «материализовать» BLOB-параметр XML_MESSAGE в виде файла на сервере приложений.

Анализ выходного XML-документа

После извлечения выходных XML-документов для двух подсистем DB2 мы формируем и заполняем компонент Model в своем Web-приложении, основанном на шаблоне MVC. Компонент Model представлен классом SubsystemConfig, в котором фактически инкапсулирована конфигурация отдельной подсистемы DB2 (другими словами, этот класс содержит ассоциированный с этой подсистемой идентификатор, а также набор ее параметров). Как правило, для представления компонента Modelприменяется технология Java Beans; однако для упрощения данного примера мы ограничились созданием обычного Java-класса. После того как мы сохранили конфигурации двух подсистем DB2 в двух экземплярах компонента Model, сервлет Controller хранит эти два экземпляра в HTTP-сессии, что впоследствии позволяет компоненту View получить к ним доступ.

Для анализа раздела с параметрами подсистемы в XML-документе мы используем Java-расширение XPath, реализованное в пакетах javax.xml.xpath. Для этого необходимо из XML-документа создать DOM-объект, к которому затем может быть применена скомпилированная XPath-процедура. В листинге 4 иллюстрируется создание DOM-объекта из BLOB-объекта XML_OUTPUT.


Листинг 4. Создание DOM-объекта из BLOB-объекта XML_OUTPUT (SPWrapper)

...

  InputStream instream = (InputStream)b_out.getBinaryStream();
  processXMLOutput(instream);

...

public void processXMLOutput(InputStream inStream) {
  DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  domFactory.setNamespaceAware(true);
  DocumentBuilder domBuilder;
  try {
    domBuilder = domFactory.newDocumentBuilder();
    Document document = domBuilder.parse(inStream);

...

Для более наглядной иллюстрации использования XPath-элементов выходной XML-документ, представляемый версией 1.0 хранимой процедуры GET_CONFIG, показан в листинге 5 в абстрагированном виде. Элементы <dict>...</dict>, которые обычно содержат более подробную информацию, показаны в свернутом виде – с целью более концентрированного представления XML-структуры.


Листинг 5. Выходная XML-структура (GET_CONFIG)

<plist version="1.0">
  <dict>
    <key>Document Type Name</key><string>Data Server Configuration Output</string>
    <key>Document Type Major Version</key><integer>1</integer>
    <key>Document Type Minor Version</key><integer>0</integer>
    <key>Data Server Product Name</key><string>DSN</string>
    <key>Data Server Product Version</key><string>8.1.5</string>
    <key>Data Server Major Version</key><integer>8</integer>
    <key>Data Server Minor Version</key><integer>1</integer>
    <key>Data Server Platform</key><string>z/OS</string>
    <key>Document Locale</key><string>en_US</string>
    <key>Common Data Sharing Group Information</key>
    <dict>...</dict>
    <key>DB2 Subsystem Specific Information</key>
    <dict>
      <dict>
        <key>Display Name</key><string>DB2 Subsystem Specific Information</string>
        <key>V81A</key>
        <dict>
          <key>Display Name</key><string>V81A</string>
          <key>DB2 Subsystem Status Information</key>
          <dict>...</dict>
          <key>DB2 Subsystem Parameters</key>
          <dict>...</dict>
          <key>DB2 Distributed Access Information</key>
          <dict>...</dict>
          <key>Active Log Data Set Information</key>
          <dict>...</dict>
          <key>Time of Last DB2 Restart</key>
            <dict>...</dict>
          <key>Resource Limit Facility Information</key>
          <dict>...</dict>
          <key>Connected DB2 Subsystem</key>
          <dict>...</dict>
        </dict>
      </dict>
    </dict>
  </dict>

На первом шаге производится извлечение идентификатора подсистемы DB2 из выходного XML-документа. В листинге 6 XPath возвращает из XML-документа набор NodeSet, в котором каждый узел содержит идентификатор подсистемы DB2 (например, V81A). С начала с помощью XPathFactory создается Java-объект XPath. Затем осуществляется компиляция Xpath-объекта и его применение к объекту XML-DOM. Для каждого идентификатора узла подсистемы, возвращенного Xpath-объектом, создается новый объект Model SubsystemConfig (см. листинг 6).


Листинг 6. Применение XPath для извлечения идентификатора подсистемы (GET_CONFIG)
				
  XPathFactory xpathFactory = XPathFactory.newInstance();
  XPath xpath = xpathFactory.newXPath();
  XPathExpression subsystemParameter;

  // Apply XPath on the DOM object
  subsystemParameter = xpath.compile("//string[text() =
          'DB2 Subsystem Specific Information']/following-sibling::key[1]");
  Object result = subsystemParameter.evaluate(document, XPathConstants.NODESET);

  NodeList nodes = (NodeList) result;
  for (int i = 0; i < nodes.getLength(); i++) {
    String subsystemID = (String)nodes.item(i).getTextContent();
    SubsystemConfig subsystem = new SubsystemConfig(subsystemID, nodes.item(i));
    subsystem.parseSubsystemConfig();
    dsGroup.add(subsystem);
  }

После извлечения идентификатора подсистемы DB2 мы начинаем заполнять объект Model. При этом мы используем узел идентификатора подсистемы в качестве нового узла контекста для следующих XPath-шагов, которые извлекают информацию о параметрах подсистемы. Xpath-шаги для получения доступа к разделам с определенной информацией о параметрах подсистемы (например, Name (имя) или Value (значение)) хранятся непосредственно в компоненте Model (а именно, в классе SubsystemConfig). Первый применяемый нами Xpath-шаг в SubsystemConfig возвращает набор NodeSet, содержащий указания на все имена параметров подсистемы. Затем по этому набору производится итеративное прохождение, при котором текущий узел имени параметра подсистемы служит новым узлом контекста для применения соответствующих дополнительных Xpath-шагов с целью извлечения последующей информации. В листинге 7 показан обрабатываемый XML-фрагмент. На расположенные справа маркеры ссылается первый столбец Таблицы 2, в котором представлен раздел выходного XML-документа GET_CONFIG, содержащий параметры подсистемы. Во втором столбце этой таблице представлены XPath-элементы для соответствующих узлов контекста. Иерархия каждого узла контекста представлена посредством нумерации. К примеру, «1.1» – это соответствующий XPath-элемент для текущего узла контекста (1).


Листинг 7. Фрагмент XML-документа, возвращаемого процедурой GET_CONFIG
				
<key>V81A</key>                                        -- (1)
<dict>
  <key>Display Name</key><string>V81A</string>
  <key>DB2 Subsystem Status Information</key>
  <dict>...</dict>
  <key>DB2 Subsystem Parameters</key>
  <dict>
    <key>Display Name</key>
    <string>DB2 Subsystem Parameters</string>
    <key>DSNHDECP</key>                                -- (1.1.1)
    <dict>
      <key>Display Name</key><
      <string>DSNHDECP</string>
      <key>AGCCSIB</key>                               -- (1.1)
      <dict>
        <key>Display Name</key><
        <string>AGCCSID</string>
        <key>Installation Panel Name</key><
        <dict>
          <key>Display Name</key><
          <string>Installation Panel Name</string>
          <key>Value</key><
          <string>DSNTIPF</string>                     -- (1.1.3)
          </dict>
        <key>Installation Panel Field Name</key>
        <dict>
          <key>Display Name</key><
          <string>Installation Panel Field Name</string>
          <key>Value</key><
          <string>ASCII CCSID</string>                 -- (1.1.4)
        </dict>
        <key>Location on Installation Panel</key><
        <dict>
          <key>Display Name</key><
          <string>Location on Installation Panel</string>
          <key>Value</key><
          <string>8</string>                           -- (1.1.5)
          </dict>
        <key>Subsystem Parameter Value</key><
        <dict>
          <key>Display Name</key><
          <string>Subsystem Parameter Value</string>
          <key>Value</key><
          <string>65534</string>                       -- (1.1.2)
        </dict>
      </dict>
    ... Further subsystem Parameters in the same control block
    </dict>
    ... further subsystem parameter control blocks
  </dict>


Таблица 2. Раздел параметров подсистемы (GET_CONFIG)
XML-структураXPath-элементы
(1)Начальный узел контекста
(1.1.1)Имя управляющего блока для текущего параметра подсистемы: ../preceding-sibling::string[1]
(1.1)Новый узел контекста, NodeSet для всех имен параметра подсистемы: ./following-sibling::dict[1]//string[text() = 'DB2 Subsystem Parameters']/following-sibling::dict/dict/string[1]
(1.1.3)Имя панели установки: ./following-sibling::key[text() = 'Installation Panel Name']/following-sibling::dict[1]/key[text() = 'Value']/following-sibling::string[1]
(1.1.4)Местоположение на панели установки: ./following-sibling::key[text() = 'Location on Installation Panel']/following-sibling::dict[1]/key[text() = 'Value']/following-sibling::string[1]
(1.1.5)Имя поля панели установки: ./following-sibling::key[text() = 'Installation Panel Field Name']/following-sibling::dict[1]/key[text() = 'Value']/following-sibling::string[1]
(1.1.2)Значение параметра подсистемы: ./following-sibling::key[text() = 'Subsystem Parameter Value']/following-sibling::dict[1]/key[text() = 'Value']/following-sibling::string[1]


Как и в случае с идентификатором подсистемы DB2, класс SubsystemConfig получает XPath-объект из XPathFactory и компилирует соответствующие XPath-элементы. Как описывалось выше, первый примененный Xpath-шаг возвращает набор NodeSet со сведениями по всем именам параметров подсистемы. Затем класс производит итеративное прохождение по всем объектам, используя очередной объект в качестве узла контекста и применяя соответствующие XPath-элементы. Соответствующий Java-код показан в листинге 8. Как только вся информация, связанная с определенным параметром подсистемы, будет извлечена, формируется новый объект класса ZParm, в котором эти значения содержатся в виде свойств. Объект класса хранится в отсортированном TreeMap-объекте zparms, в котором в качестве ключа поиска и сортировки выбирается имя параметра подсистемы. Теперь мы можем с легкостью получить отсортированный список имен параметров подсистемы. Кроме того, мы можем без каких-либо трудностей получить дополнительную информацию о любом параметре – для этого достаточно просмотреть отображенный объект ZParm.


Листинг 8. Извлечение информации о параметре подсистемы (класс SubsystemConfig)

  private String                  subsystemID = null;
  private TreeMap<String, ZParm>  zparms      = null;
  private Node                    contextNode = null;

  /* XPath to subsystem parameter name */
  private final String xpathZPName = "./following-sibling::dict[1]//string[text() = " +
          "'DB2 Subsystem Parameters']/following-sibling::dict/dict/string[1]";
  /* XPath to control block name */
  private final String xpathCBN = "../preceding-sibling::string[1]";
  /* XPath to subsystem parameter value */
  private final String xpathZPValue = "./following-sibling::key[text() = " +
          "'Subsystem Parameter Value']/following-sibling::dict[1]/" +
          "key[text() = 'Value']/following-sibling::string[1]";

  ...

  XPathFactory xpathFactory = XPathFactory.newInstance();
  XPath xpath = xpathFactory.newXPath();
  XPathExpression subsystemParameter = xpath.compile(xpathZPName);
  NodeList zParmNodes = (NodeList)subsystemParameter.evaluate(
          contextNode, XPathConstants.NODESET);
  for (int i = 0; i < zParmNodes.getLength(); i++) {
    currentzParmNode = zParmNodes.item(i);
    zParmName = (String)currentzParmNode.getTextContent();

    controlBlockName = extractInformation(currentzParmNode, xpathCBN).getTextContent();
    zParmValue = extractInformation(currentzParmNode, xpathZPValue).getTextContent();
    ...

    /* Create zParm object */
    zparms.put(zParmName, new ZParm(zParmName, controlBlockName, installPanelName,
            locationOnInstallPanel, installPanelFieldName, zParmValue));
  }

  ...

private Node extractInformation(Node contextNode, String xpathString) {
  Node node = null;
  try {
    XPathFactory xpathFactory = XPathFactory.newInstance();
    XPath xpath = xpathFactory.newXPath();
    XPathExpression subsystemParameter = xpath.compile(xpathString);
    node = (Node)subsystemParameter.evaluate(contextNode, XPathConstants.NODE);
  } catch (XPathExpressionException e) {
    e.printStackTrace();
  }
  return node;
}

После того как потоки сервлета завершат свою работу по сбору информации о параметре подсистемы, в объекте сессии будут сохранены два объекта Model со следующими фиксированными именами для поиска: zParmComp.DSGroup1, zParmComp.DSGroup2. Затем сервлет перенаправит исходный HTTP-запрос к JSP-странице, которая в Web-приложении выполняет функции компонента View.


Листинг 9. Перенаправление к компоненту View (ZpCompServlet)
				
  /* Get the Data Sharing group ArrayList object */
  ArrayList dsGroup1 = spw[0].get_ds_group();
  ArrayList dsGroup2 = spw[1].get_ds_group();

  /* Forward object to View JSP */
  session.setAttribute("zParmComp.DSGroup1", dsGroup1);
  session.setAttribute("zParmComp.DSGroup2", dsGroup2);
  String jspURL="/DisplayConfig.jsp";
  ServletContext sc = getServletContext();
  RequestDispatcher rd = sc.getRequestDispatcher(jspURL);
  rd.forward(req, res);

После того как сервлет перенаправит HTTP-запрос к компоненту View, будет произведена обработка JSP-страницы DisplayConfig. Сначала эта JSP-страница обращается к объектам Model в HTTP-сессии, для чего выполняет поиск с помощью совместно используемых строковых констант zParmComp.DSGroup1, zParmComp.DSGroup2. Затем эта JSP-страница обращается к двум TreeMap-объектам zparms и получает два набора keySets. JSP-страница осуществляет итеративное прохождение по этим наборам и в случае, если оба ключа совпадают (другими словами, в случае совпадения имен параметра) сравнивает значения этого параметра и выводит их. В противном случае отображается наименьшая комбинация имя/значение, после чего из отсортированного списка извлекается следующий элемент. Для визуального представления возможных несоответствий в этих двух подсистемах мы применяем соответствующие цветовые обозначения.

Значения параметров подсистемы показаны как гиперссылки. После того, как пользователь нажимает указателем мыши на значение параметра, соответствующая ссылка инициирует HTTP-запрос к сервлету ZpCompServlet с action-параметром GETZPARM и с двумя дополнительными атрибутами, которые определяют идентификатор подсистемы, а также имя параметра. Пример.

ZpCompServlet?action=GETZPARM&ssid=V81A&zParm=AGCCSIB

Затем этот сервлет проверяет два объекта сессии на предмет того, не представляют ли они требуемый идентификатор подсистемы DB2, после чего извлекает соответствующий объект ZParm из TreeMap. После этого данный объект хранится в HTTP-сессии.

И, наконец, сервлет снова перенаправляет исходный HTTP-запрос к другому JSP-компоненту View под названием DisplayZParm. Этот JSP-компонент извлекает из сессии объект ZParm и создает HTTP-ответ, содержащий информацию объектов.

В этой статье детали JSP-реализации не рассматриваются, поскольку это не более чем средство для демонстрации информационных возможностей хранимой процедуры GET_CONFIG. Описанные функциональные возможности реализованы в полном исходном коде, ссылка на который приведена в разделе Загрузка.


Библиотека Jakarta Commons Configuration

Вместо подхода на основе XPath, описанного выше в разделе для Web-приложения, можно использовать существующий набор классов, который обеспечивает удобный доступ из вашего приложения к XML-документу PList, возвращаемому процедурой GET_CONFIG. Этот API-интерфейс к документам PList предоставляется библиотекой Jakarta Commons Configuration (см. раздел Ресурсы). Эта библиотека содержит реализацию XMLPropertyListConfiguration, которая позволяет извлекать из XML-документа значения определенных ключей, а также конструировать новые и изменять существующие XML-документы PList. В следующем листинге 10 показано, как создавать XMLPropertyListConfiguration из выходного документа GET_CONFIG XML, материализованного в виде файла. Программный код извлекает значение ключа Document Type Name (другими словами, Data Server Configuration Output), а также название и версию сервера данных. Для исполнения этого кода потребуются следующие JAR-файлы из библиотеки Jakarta Commons Configuration:

  • commons-lang
  • commons-logging
  • commons-collections
  • commons-digester
  • commons-beanutils
  • commons-codec
  • commons-configuration

Листинг 10. Использование Jakarta Commons Configuration
				
  XMLPropertyListConfiguration config = 
            new XMLPropertyListConfiguration("xml_output_gc.xml");
  System.out.println(config.getProperty("Document Type Name"));
  System.out.println(config.getProperty("Data Server Product Name"));
  System.out.println(config.getProperty("Data Server Product Version"));
 

Конструктор XMLPropertyListConfiguration пытается проверить предоставленный XML-документ на соответствие определению PList DTD. В текущей реализации (версия 1.5) мы не можем в явном виде указать конструктору, что ему следует игнорировать эту проверку. Хранимые процедуры Common SQL API не имеют тега <!DOCTYPE>, определяющего DTD, по которому должна производиться валидация. Поэтому следует иметь в виду, что в настоящее время конструктор будет выдавать конфигурационное исключение, тем не менее вы сможете продолжить использование этого API-интерфейса для обработки документа.

Подробный пример применения библиотеки Jakarta Commons Configuration приведен в Приложении A к публикации серии IBM Redbooks под названием «DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond» (см. раздел Ресурсы).


Заключение

Эта статья представляет собой введение в комплект хранимых процедур Common SQL API, который доступен для всех основных серверов данных IBM, в том числе для DB2 for z/OS и для DB2 LUW. В статье иллюстрируется использование хранимой процедуры GET_CONFIG — в качестве одного из элементов API-интерфейса — в простом zParm-инструменте для сравнения разных подсистем DB2. Представленный в статье учебный код может быть использован в качестве основы для построения более сложных и более гибких приложений. Например, вы можете параметризировать свое приложение для динамического выбора нужных подсистем DB2 в процессе исполнения или включить в него процедуру GET_SYSTEM_INFO для распространения его функциональных возможностей на информацию об операционной системе.



Загрузка

ОписаниеИмяРазмерМетод загрузки
Source code for the sample applicationCSA-sample.zip13KBHTTP

Информация о методах загрузки


Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Об авторах

Кнут Стольц (Knut Stolze) начал работать с DB2, когда в 1999 году он присоединился к IBM в качестве временного научного сотрудника в Silicon Valley Lab, США, где он работал над DB2 Image Extender. Он перешел в команду разработчиков DB2 Spatial Extender и был ответственным за совершенствование удобства использования и производительности данного продукта, а также за обеспечение его соответствия стандартам. В период с 2002 по 2006 год Кнут был студентом отделения философии и помощником преподавателя в Университете г. Йена, Германия. В то же время он продолжал работать в IBM, участвуя в разработке Information Integrator. Сегодня Кнут входит в команду разработчиков, отвечающую за функционал Admin Enablement в DB2 for z/OS. С ним можно связаться через новостные группы newsgroups comp.databases.ibm-db2 и ibm.software.db2.udb.spatial или через электронную почту stolze@de.ibm.com.

Марсель Кутш (Marcel Kutsch) является инженером по программному обеспечению в лаборатории IBM в Бёблингене (Германия). В настоящее время он занимается проектированием и созданием хранимых процедур, а также одного из компонентов DB2 for z/OS – планировщика административных задач. До прихода в IBM в качестве постоянного сотрудника М. Кутш работал в качестве стажера в Исследовательском центре IBM Almaden, где занимался оптимизацией запросов для продукта DB2 for Linux, UNIX и Windows. Его первой областью деятельности в IBM после окончания университета в 2005 г. были функции автономной работы продукта DB2.

Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Спасибо. Эта запись была помечена для модератора.


Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Сообщение о нарушении не было отправлено. Попробуйте, пожалуйста, позже.


developerWorks: вход


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Выберите ваше отображаемое имя

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

(Должно содержать от 3 до 31 символа.)


Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Оценить эту статью

Комментарии

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Information Management, Технология Java
ArticleID=458912
ArticleTitle=Применение хранимых процедур Common SQL API продукта DB2 for z/OS в инструментальных приложениях
publish-date=12252009
author1-email=stolze@de.ibm.com
author1-email-cc=
author2-email=kutschm@de.ibm.com
author2-email-cc=

Теги

Help
Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Используйте ползунок, чтобы отразить больше или меньше тегов.

КнопкаПопулярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere).

Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).

Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Кнопка Популярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere). Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).