Онлайн библиотека PLAM.RU


  • Создание таблицы Phone.dbf в Microsoft Access 
  • Настройка источника данных ODBC
  • Примеры сценариев
  • Копирование данных из XML-файла в таблицу БД
  • Просмотр записей в таблице 
  • Получение информации о полях и записях таблицы
  • Сортировка записей в таблице 
  • Фильтрация записей в таблице 
  • Перемещение в наборе записей 
  • Доступ к БД без создания DSN
  • Глава 9

    Использование в сценариях баз данных

    На практике довольно часто возникают задачи, для решения которых необходимо из сценариев получать доступ к данным, хранящимся во внешних базах самого различного формата (структурированные текстовые файлы, таблицы DBF и Paradox, базы данных Microsoft Access и Microsoft SQL Server и т.д.). Это довольно просто можно сделать с помощью технологии Microsoft ADO (ActiveX Data Objects). Объекты ADO являются частью компонентов доступа к данным Microsoft (MDAC, Microsoft Data Access Components), которые поставляются, например, с браузером Microsoft Internet Explorer версии 5.0 и выше (таким образом, в Windows ХР эти компоненты присутствуют изначально) или могут быть свободно получены с сервера Microsoft (http://msdn.microsoft.com/data/download.htm).

    Мы не будем здесь останавливаться на объектной модели и принципах работы ADO (желающие подробнее разобраться с этими вопросами могут обратиться к документации MSDN), а здесь лишь разберем несколько конкретных примеров работы с таблицей самой простой структуры: DBF- формата (до появления XML формат DBF широко применялся для обмена данными между разными автоматизированными системами, да и сейчас продолжает поддерживаться многими производителями программных продуктов). Как и в предыдущих главах, здесь будут использоваться данные записной книжки (ниже мы создадим сценарий, который будет копировать в таблицу информацию из XML-файла book.xml, с которым мы работали ранее).

    Создать DBF-таблицу можно с помощью систем управления базами данных (СУБД) FoxPro, Microsoft Access или программы Microsoft Excel. Мы опишем процесс создания таблицы в Microsoft Access.

    Создание таблицы Phone.dbf в Microsoft Access 

    Первом шагом при создании таблицы в любой базе данных является определение структуры этой таблицы — нужно определить имена, типы и размеры всех полей. Мы назовем нашу таблицу Phone.dbf; структура ее описана в табл. 9.1.


    Таблица 9.1. Структура таблицы Phone.dbf

    Имя поля Тип Размер (символов)
    LastName Символьный 50
    Name Символьный 50
    Phone Символьный 12
    Street Символьный 50
    House Символьный 4
    App Символьный 4
    Notes Символьный 100

    Определившись со структурой таблицы, запустим Microsoft Access и создадим новую базу данных (рис. 9.1).


    Рис. 9.1. Новая база данных в Microsoft Access


    Выберем пункт Создание таблиц в режиме конструктора (Construct tables), последовательно введем названия полей, выбирая для каждого поля символьный тип данных и устанавливая нужную длину (рис. 9.2).

    Рис. 9.2. Создание структуры новой таблицы


    Затем закроем окно конструктора и введем название "Phone" в диалоговое окно сохранения таблицы (рис. 9.3).

    Рис. 9.3. Сохранение новой таблицы


    Так как мы не будем определять ключевые поля в нашей таблице, то нужно ответить отрицательно на соответствующий вопрос (рис. 9.4).

    Рис. 9.4. Запрос на создание ключевых полей


    После этого выделим таблицу Phone и выберем пункт Экспорт (Export) в меню Файл (File). В диалоговом окне Экспорт объекта (Object Export) выберем нужный каталог для сохранения таблицы Phone (далее таким каталогом мы будем считать C:\Tabl), укажем в качестве типа файла dBase IV и нажмем кнопку Сохранить (Save) (рис. 9.5).


    Рис. 9.5. Экспорт таблицы Phone в формате DBF


    Теперь пустая DBF-таблица нужной нам структуры сохранена на диске и программу Microsoft Access можно закрыть.

    Настройка источника данных ODBC

    Для получения доступа к созданной DBF-таблице из сценария WSH мы воспользуемся технологией ODBC (Open DataBase Connectivity). ODBC — это стандартное средство Microsoft для работы с реляционными базами данных различных форматов и производителей, способное обрабатывать запросы к базам на языке SQL (Structured Query Language, язык структурированных запросов).

    Замечание

    Для начального ознакомления с языком SQL можно порекомендовать книгу [4].

    Для более глубокого изучения языка SQL рекомендуется книга Дж. Грофф, П. Вайнберг SQL: Полное руководство: Пер. с англ. — 2-е изд., перераб. и доп. — Киев: Издательская группа BHV, 2001. — 816 с.

    Вначале нам понадобится завести в системе ODBC-запись для связи с нашей базой, т.е. создать новый DSN (Data Source Name, имя источника данных). В Windows ХР это делается следующим образом.

    Загрузим Панель управления (Control Panel) Windows (меню Пуск (Start)) и переключимся к классическому виду (рис. 9.6). 

    Рис. 9.6. Классический вид панели управления Windows ХР


    Последовательно выберем пункты Администрирование (Administrative tools) и Источники данных (ODBC) (Data sources (ODBC)). В появившемся диалоговом окне выберем вкладку Системный DSN (System DSN), что позволит создать DSN, доступный всем пользователям компьютера (рис. 9.7).

    Рис. 9.7. Администратор источников данных ODBC в Windows ХР


    Нажмем кнопку Добавить (Add) и в появившемся окне выберем драйвер Microsoft dBase Driver (*.dbf) (рис. 9.8).

    Рис. 9.8. Список драйверов ODBC


    После нажатия кнопки Готово (Done) появится новое окно, описывающее параметры подключения к нашей базе. Здесь в поле Имя источника данных (Data Source Name) напишем имя "PhoneDS", через которое будет осуществляться доступ к нашей базе. Для выбора пути к базе данных снимем флажок Использовать текущий каталог (Use Current Directory) и нажмем на кнопку Выбор каталога (Select Directory). В открывшемся окне укажем путь C:\Tabl и нажмем OK (рис. 9.9).

    Рис. 9.9. Параметры источника данных ODBC


    Для завершения настройки DSN нажмем кнопку OK и закроем окно ODBC.

    Примеры сценариев

    Начнем мы с того, что скопируем данные записной книжки из XML-файла book.xml в DBF-таблицу Phone.dbf (сценарий InsertRecords.js). Все остальные сценарии, которые рассматриваются в этой главе, будут работать уже с этой таблицей.

    Копирование данных из XML-файла в таблицу БД

    Напишем сценарий InsertRecords.js, который будет извлекать данные из XML-файла book.xml и добавлять записи с этими данными в таблицу Phone.dbf, для доступа к которой мы предварительно создали DSN (рис. 9.9).

    Сценарий InsertRecords.js будет состоять из нескольких функций, главной из которых является

    Main()
    . В этой функции сначала создается объект
    WshShell
    и определяется путь к XML-файлу, который должен находиться в текущем каталоге:

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Путь к XML-файлу с данными

    PathBook=WshShell.CurrentDirectory+"\\book.xml";

    Для доступа к таблице Phone мы создаем объект

    Connection
    , который позволяет с помощью метода
    Open()
    устанавливать связь с заданной базой данных. Для этого необходимо в качестве параметра
    Open()
    указать строку с именем источника данных, к которому происходит обращение (в нашем случае эта строка имеет вид "DSN=PhoneDS"):

    //Создаем объект Connection

    Connect=WScript.CreateObject("ADODB.Connection");

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect="DSN=PhoneDS";

    //Устанавливаем связь с БД

    Connect.Open(SConnect);

    После этого происходит вызов функции

    XMLToBase()
    , в которой происходит разбор XML-файла с помощью объектной модели XML DOM (применение XML DOM было подробно описано в главе 7).

    //Копирование данных из XML-файла в таблицу Phone

    function XMLToBase() {

     var XML,Root,NomRec,CurrNode,i;

     //Создаем объект XML DOM

     XML = WScript.CreateObject("Msxml.DOMDocument");

     //Загружаем XML-документ из файла

     XML.load(PathBook);

     //Сохраняем в переменной Root ссылку на корневой элемент документа

     Root=XML.documentElement;

     //Перебираем все дочерние элементы первого уровня вложенности

     //для корневого элемента

     for (i=1; i<=Root.childNodes.length-1;i++) {

      //Выделяем в коллекции XML-элементов i-й элемент

      CurrNode=Root.childNodes.item(i);

      //Вставляем новую запись в таблицу Phone

      PersonToTable(CurrNode);

     }

    }
     

    Как мы видим, в функции

    XMLToBase()
    определяется цикл
    for
    , в котором для каждого XML-элемента, содержащего данные об одном человеке, происходит вызов функции
    PersonToTable(XNode)
    . В функции
    PersonToTable(XNode)
    формируется SQL-запрос
    INSERT INTO Phone…
    , который позволяет вставить в таблицу Phone новую запись с заданными значениями полей, например:

    INSERT INTO Phone (LastName, Name, Phone, Street, House, App, Notes)

    VALUES ('Иванов', 'Иван', '17-17-17', 'Садовая', '4', '6', 'Очень хороший человек')

    Строится строка с SQL-запросом (переменная SSQL) следующим образом:

    //Строим список значений полей добавляемой записи

    SSQL+="'"+GetTagVal(XNode, "LastName")+"',";

    SSQL+="'"+GetTagVal(XNode, "Name")+"',";

    SSQL+="'"+GetTagVal(XNode, "Phone")+"',";

    SSQL+="'"+GetTagVal(XNode, "Street")+"',";

    SSQL+="'"+GetTagVal(XNode, "House")+"',";

    SSQL+="'"+GetTagVal(XNode, "App")+"',";

    SSQL+="'"+GetTagVal(XNode, "Note")+"'";

    //Формируем текст SQL-запроса для вставки записи

    SSQL="INSERT INTO Phone (LastName, Name, Phone, Street, House, App, Notes) VALUES ("+SSQL+")";

    После формирования переменной SSQL происходит вызов SQL-запроса с помощью метода

    Execute()
    объекта
    Connection
    :

    //Выполняем подготовленный SQL-запрос (добавляем запись в таблицу)

    Connect.Execute(SSQL);

    После окончания копирования данных в функции

    Main()
    выводится соответствующее сообщение:

    //Выводим сообщение об окончании переноса данных

    WshShell.Popup("Данные из XML-файла в таблицу перенесены!", 0, "Работа с базой данных", vbInformation+vbOkOnly);

    Полностью текст сценария InsertRecords.js приведен в листинге 9.1.

    Листинг 9.1. Копирование данных из XML-файла в таблицу БД

    /*******************************************************************/

    /* Имя: InsertRecords.js                                           */

    /* Язык: JScript                                                   */

    /* Описание: Копирование данных из XML-файла таблицу базы          */

    /*           данных                                                */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell, //Экземпляр объекта WshShell

     BasePath, //Путь к текущему каталогу

     PathBook, //Путь к файлу с данными

     NomRec=0, //Счетчик количества записей

     SConnect, //Строка с параметрами соединения с БД

     Connect;  //Экземпляр объекта Connection

    //Инициализируем константы для диалоговых окон

    var vbInformation=64,vbOkOnly=0;


    //Определение значения тега tgName XML-элемента obj

    function GetTagVal(obj, tgName) {

     var ElemList;

     //Создаем коллекцию дочерних для obj элементов, которые

     //задаются тегом tgName

     ElemList=obj.getElementsByTagName(tgName);

     //Проверяем, есть ли в коллекции ElemList элементы

     if (ElemList.length>0)

      //Возвращаем значение тега tgName

      return ElemList.item(0).text

     else return "";

    }

    //Вставка в таблицу одной записи

    function PersonToTable(XNode) {

     var SSQL="";  //Переменная для формирования текста SQL-запроса

     //Строим список значений полей добавляемой записи

     SSQL+="'"+GetTagVal(XNode,"LastName")+"',";

     SSQL+="'"+GetTagVal(XNode,"Name")+"',";

     SSQL+="'"+GetTagVal(XNode,"Phone")+"',";

     SSQL+="'"+GetTagVal(XNode,"Street")+"',";

     SSQL+="'"+GetTagVal(XNode,"House")+"',";

     SSQL+="'"+GetTagVal(XNode,"App")+"',";

     SSQL+="'"+GetTagVal(XNode,"Note")+"'";

     //Формируем текст SQL-запроса для вставки записи

     SSQL="INSERT INTO Phone (LastName,Name,Phone,Street,House,App,Notes) VALUES ("+SSQL+")";

     //Выполняем подготовленный SQL-запрос (добавляем запись в таблицу)

     Connect.Execute(SSQL);

    }

    //Копирование данных из XML-файла в таблицу Phone

    function XMLToBase() {

     var XML,Root,NomRec,CurrNode,i;

     //Создаем объект XML DOM

     XML = WScript.CreateObject("Msxml.DOMDocument");

     //Загружаем XML-документ из файла

     XML.load(PathBook);

     //Сохраняем в переменной Root ссылку на корневой элемент документа

     Root=XML.documentElement;

     //Перебираем все дочерние элементы первого уровня вложенности

     //для корневого элемента

     for (i=1; i<=Root.childNodes.length-1;i++) {

      //Выделяем в коллекции XML-элементов i-й элемент

      CurrNode=Root.childNodes.item(i);

      //Вставляем новую запись в таблицу Phone

      PersonToTable(CurrNode);

     }

    }


    //Основная запускная функция

    function Main() {

     //Создаем объект WshShell

     WshShell = WScript.CreateObject("WScript.Shell");

     //Путь к XML-файлу с данными

     PathBook=WshShell.CurrentDirectory+"\\book.xml";

     //Создаем объект Connection

     Connect=WScript.CreateObject("ADODB.Connection");

     //Формируем строку с параметрами соединения с БД

     //(указываем нужный DSN)

     SConnect="DSN=PhoneDS";

     //Устанавливаем связь с БД

     Connect.Open(SConnect);

     //Копируем данные из XML-файла в таблицу БД

     XMLToBase();

     //Выводим сообщение об окончании переноса данных

     WshShell.Popup("Данные из XML-файла в таблицу перенесены!", 0,

      "Работа с базой данных",vbInformation+vbOkOnly);

    }

    /*******************  Начало  **********************************/

    Main();

    /*************  Конец *********************************************/

    Просмотр записей в таблице 

    После того как мы произвели копирование записной книжки в таблицу Phone.dbf, возникает естественное желание просмотреть из сценария введенные записи. Напишем для этой цели сценарий ListRecords1.js, результат работы которого представлен на рис. 9.10.

    Рис. 9.10. Записи из таблицы Phone


    Основным объектом, позволяющим получить доступ к записям таблицы, является

    Recordset
    , который представляет собой набор записей, полученных, например, в результате выполнения SQL-запроса. Создается объект
    Recordset
    следующим образом (экземпляром объекта будет переменная
    RS
    ):

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    Все строки из таблицы Phone выбираются с помощью следующего SQL- запроса:

    SELECT * from Phone

    Этот запрос записывается в переменную

    SSource
    :

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    Для занесения в RS требуемого набора записей используется метод

    Open()
    , в качестве параметров которого указываются две строки. В первой из них должен содержаться SQL-запрос (переменная
    SSource
    ), а во второй — параметры соединения с базой данных (в нашем случае это переменная
    SConnect
    , в которой записан нужный DSN):

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Открываем набор записей - результат запроса

    RS.Open(SSource, SConnect);

    Текст, который будет в конце сценария выведен на экран, будет храниться в переменной SOut. Первоначально в эту переменную записываем заголовок:

    SOut="BCE ЗАПИСИ ИЗ ТАБЛИЦЫ phone.dbf:\n";

    Для перемещения по записям набора

    RS
    используется так называемый курсор, который после выполнения метода
    Open()
    автоматически устанавливается на первую запись. Перебор всех записей производится в цикле
    while
    , условием выхода из которого является перемещение курсора за последнюю запись таблицы (при этом свойство
    EOF
    объекта
    Recordset
    станет равным
    True
    ).

    //Перебираем все записи набора данных RS

    while (!RS.EOF) {

     …

    }

    Для доступа к полям текущей записи используется коллекция

    Fields
    , содержащая значения всех полей; чтобы получить значение конкретного поля, нужно указать в круглых скобках имя этого поля в кавычках, скажем,
    RS.Fields("Name")
    . Метод
    MoveNext()
    выполняет переход к следующей записи таблицы:

    while (!RS.EOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+ RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к следующей записи

     RS.MoveNext();

    }

    Закрывается объект

    Recordset
    с помощью метода
    Close()
    :

    //Закрываем объект Recordset

    RS.Close();

    После этого сформированный в переменной sout текст выводится на экран:

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    Полностью сценарий ListRecords1.js приведен в листинге 9.2.

    Листинг 9.2. Просмотр записей таблицы

    /*******************************************************************/

    /* Имя: ListRecords1.js                                            */

    /* Язык: JScript                                                   */

    /* Описание: Просмотр записей из таблицы базы данных               */

    /*******************************************************************/

    //Объявляем переменные

    var

     RS,       //Экземпляр объекта Recordset

     SSource,  //Строка с текстом SQL-запроса к БД

     SConnect, //Строка с параметрами соединения с БД

     SOut,     //Строка, в которой сохраняется выходная информация

     s;

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Открываем набор записей-результат запроса

    RS.Open(SSource,SConnect);

    SOut="ВСЕ ЗАПИСИ ИЗ ТАБЛИЦЫ phone.dbf:\n";

    //Перебираем все записи набора данных RS

    while (!RS.EOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к следующей записи

     RS.MoveNext();

    }

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    /*************  Конец *********************************************/


    Для получения набора записей

    Recordset
    можно не создавать его непосредственно, как это было сделано в ListRecords1.js, а воспользоваться методом
    Execute()
    объекта
    Connection
    . В качестве иллюстрации такого подхода рассмотрим сценарий ListRecords2.js (листинг 9.3).

    Сначала в этом сценарии создается объект

    Connection
    и устанавливается связь с нашей базой данных (
    DSN=PhoneDs
    ):

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Connection

    Connect=WScript.CreateObject("ADODB.Connection");

    //Устанавливаем связь с БД

    Connect.Open(SConnect);

    Для получения всех записей из таблицы Phone используется тот же запрос, что и в сценарии ListRecords1.js:

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Выполняем SQL-запрос, в результате создается объект Recordset

    RS=Connect.Execute(SSource);

    В результате переменная

    RS
    становится нужным нам экземпляром объекта
    Recordset
    . После этого записи из набора
    RS
    обрабатываются точно так же, как в сценарии ListRecords1.js.

    Листинг 9.3. Просмотр записей таблицы с использованием объекта Connection

    /*******************************************************************/

    /* Имя: ListRecords2.js                                            */

    /* Язык: JScript                                                   */

    /* Описание: Просмотр записей из таблицы базы данных               */

    /*           с использованием объекта Connection                   */

    /*******************************************************************/

    //Объявляем переменные

    var

     RS,       //Экземпляр объекта Recordset

     Connect,  //Экземпляр объекта Connection

     SSource,  //Строка с текстом SQL-запроса к БД

     SConnect, //Строка с параметрами соединения с БД

     SOut,     //Строка, в которой сохраняется выходная информация

     s;

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Connection

    Connect=WScript.CreateObject("ADODB.Connection");

    //Устанавливаем связь с БД

    Connect.Open(SConnect);

    //Выполняем SQL-запрос, в результате создается объект Recordset

    RS=Connect.Execute(SSource);

    SOut="ВСЕ ЗАПИСИ ИЗ ТАБЛИЦЫ phone.dbf:\n";

    //Перебираем все записи набора данных RS

    while (!RS.EOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к следующей записи

     RS.MoveNext();

    }

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    /*************  Конец *********************************************/

    Получение информации о полях и записях таблицы

    Иногда бывает необходимо определить число и названия полей или подсчитать общее число записей в таблице. Приведенный в листинге 9.4 сценарий TableInfo.js выводит на экран диалоговое окно, где приведены названия всех полей и общее количество записей таблицы Phone.dbf (рис. 9.11).

    Рис. 9.11. Информация о полях и записях таблицы Phone


    В TableInfo.js для доступа к таблице Phone создается объект

    Recordset
    :

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    Перед открытием набора записей с помощью метода

    Open()
    нужно установить свойство
    CursorType
    объекта
    Recordset
    равным 3 (при этом создается статическая копия таблицы, что позволяет получить информацию о полях и записях):

    //Задаем статический курсор

    RS.CursorType = 3;

    //Открываем набор записей - результат запроса

    RS.Open(SSource, SConnect);

    После этого в коллекции

    Fields
    будут содержаться все поля набора записей
    Recordset
    , а в свойстве
    RecordCount
    — число записей в этом наборе:

    //Определяем число полей в наборе данных

    RS_NomFields = RS.Fields.Count;

    //Определяем число записей в наборе данных

    RS_NomRecs = RS.RecordCount;

    В переменной

    SOut
    будет формироваться текст для вывода на экран:

    SOut="ТАБЛИЦА Phone СОДЕРЖИТ "+NomFields+" ПОЛЯ(ЕЙ):\n\n";

    Для получения списка полей мы перебираем в цикле

    for
    все элементы коллекции
    Fields
    :

    //Перебираем все поля набора данных RS

    for (i=0; i<RS.Fields.Count; i++) {

     //Формируем строку с номером и именем поля таблицы

     SOut+"Поле N "+i+": "+RS.Fields(i).Name+"\n";

    }

    После завершения цикла к переменной

    SOut
    добавляется информация о количестве записей, набор записей
    RS
    закрывается и значение переменной
    SOut
    выводится на экран:

    SOut+="\nИ "+NomRecs+" ЗАПИСЬ(ЕЙ)";

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    Листинг 9.4. Получение информации о полях таблицы

    /*******************************************************************/

    /* Имя: TableInfo.js                                               */

    /* Язык: JScript                                                   */

    /* Описание: Получение информации о полях таблицы                  */

    /*******************************************************************/

    //Объявляем переменные

    var

     RS,       //Экземпляр объекта Recordset

     SSource,  //Строка с текстом SQL-запроса к БД

     SConnect, //Строка с параметрами соединения с БД

     SOut,     //Строка, в которой сохраняется выходная информация

     NomField, //Количество полей в таблице

     NomRecs,  //Количество записей в таблице

     i;

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Задаем статический курсор

    RS.CursorType = 3;

    //Открываем набор записей-результат запроса

    RS.Open(SSource,SConnect);

    //Определяем число полей в наборе данных RS

    NomFields = RS.Fields.Count;

    //Определяем число записей в наборе данных RS

    NomRecs = RS.RecordCount;

    SOut="ТАБЛИЦА Phone СОДЕРЖИТ "+NomFields+" ПОЛЯ(ЕЙ):\n\n";

    //Перебираем все поля набора данных RS

    for (i=0; i<RS.Fields.Count; i++) {

     //Формируем строку с номером и именем поля таблицы

     SOut+="Поле N "+i+": "+RS.Fields(i).Name+"\n";

    }

    SOut+="\nИ "+NomRecs+" ЗАПИСЬ(ЕЙ)";

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    /*************  Конец *********************************************/

    Сортировка записей в таблице 

    Используя предложение

    ORDER BY
    в операторе
    SELECT
    , можно получить из источника данных записи, отсортированные по какому-либо полю. Например, следующий SQL-запрос

    SELECT * FROM Phone ORDER BY LastName

    вернет упорядоченный по полю

    LastName
    набор, содержащий все записи из таблицы Phone (рис. 9.12).

    Рис. 9.12. Сортировка записей таблицы Phone по полю LastName


    Мы напишем сценарий SortRecords.wsf, с помощью которого можно будет выводить записи из таблицы Phone, отсортированные либо по фамилии (поле

    LastName
    ), либо по телефону (поле
    Phone
    ). Выбор осуществляется с помощью ввода соответствующего значения в диалоговом окне (рис. 9.13).

    Рис. 9.13. Выбор поля для сортировки


    Само диалоговое окно реализуется с помощью VBScript-функции

    WSHInputBox(Message, Title)
    :

    Function WSHInputBox(Message, Title)

     'Выводим диалоговое окно со строкой ввода

     WSHInputBox = InputBox(Message,Title)

    End Function

    Эта функция вызывается из написанной на JScript части сценария следующим образом:

    //Формируем текст сообщения в диалоговом окне ввода

    SMenu="1 - Сортировка по фамилии\n";

    SMenu+="2 - Сортировка по телефону\n";

    SMenu+="\n\nКоманда:";

    //Выводим диалоговое окно для ввода режима сортировки

    Res=WSHInputBox(SMenu, "Работа с базой данных");

    Введенное в диалоговом окне значение записывается в переменную

    Res
    и анализируется в операторе
    switch
    :

    //Анализируем введенное значение

    switch (Res) {

    case "1": {

     SSort="LastName";

     break;

    }

    case "2": {

     SSort="Phone";

     break;

    }

    default: {

     WScript.Echo("Вы ввели неправильное значение!");

     WScript.Quit();

    }

    }

    После того как в переменную

    SSort
    занесено имя поля, по которому нужно производить сортировку, мы можем полностью сформировать нужный SQL-запрос к таблице Phone:

    //Формируем SQL-запрос к таблице Phone SSource = "SELECT * FROM Phone ORDER BY "+SSort;

    Оставшаяся часть сценария взята из сценария ListRecords1.js и комментариев не требует.

    Полностью текст сценария SortRecords.wsf приведен в листинге 9.5.

    Листинг 9.5. Сортировка записей в таблице по заданному полю

    <job id="SortRecs">

    <runtime>

    <description>

    Имя: SortRecords.wsf

    Описание: Сортировка записей таблицы БД по заданному полю

    </description>

    </runtime>

    <script language="VBScript">

    'Функция для реализации диалогового окна со строкой ввода

    'в сценариях JScript

    Function WSHInputBox(Message,Title)

    'Выводим диалоговое окно со строкой ввода

    WSHInputBox = InputBox(Message,Title)

    End Function

    </script>

    <script language="JScript">

    //Объявляем переменные

    var

     RS,       //Экземпляр объекта Recordset

     SSource,  //Текст SQL-запроса к БД

     SConnect, //Строка с параметрами соединения с БД

     SOut,     //Строка, в которой сохраняется выходная информация

     Res,      //Результат ввода в диалоговом окне

     SSort,    //Имя поля таблицы, по которому будет производиться сортировка

     SMenu,    //Текст сообщения в диалоговом окне ввода

     s;

    //Формируем текст сообщения в диалоговом окне ввода

    SMenu="1 - Сортировка по фамилии\n";

    SMenu+="2 - Сортировка по телефону\n";

    SMenu+="\n\nКоманда:";

    //Выводим диалоговое окно для ввода режима сортировки

    Res=WSHInputBox(SMenu,"Работа с базой данных");

    //Анализируем введенное значение

     switch (Res) {

     case "1": {

      SSort="LastName";

      break;

     }

     case "2": {

      SSort="Phone";

      break;

     }

     default: {

      WScript.Echo("Вы ввели неправильное значение!");

      WScript.Quit();

     }

    }

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone ORDER BY "+SSort;

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Открываем набор записей-результат запроса

    RS.Open(SSource,SConnect);

    SOut="ВСЕ ЗАПИСИ ИЗ ТАБЛИЦЫ phone.dbf:\n";

    //Перебираем все записи набора данных RS

    while (!RS.EOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к следующей записи

     RS.MoveNext();

    }

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    </script>

    </job>

    Фильтрация записей в таблице 

    Оператор

    SELECT
    позволяет выбирать из источника данных не все записи, а лишь те, которые удовлетворяют определенному критерию. Для этой цели в операторе
    SELECT
    применяется оператор
    WHERE
    . Например, следующий SQL-запрос

    SELECT * FROM Phone WHERE (LastName LIKE 'П%')

    вернет только те записи таблицы Phone, у которых значение поля

    LastName
    начинается на букву 'П' (шаблон '%' означает любое число любых символов).

    Мы напишем сценарий FilterRecords.wsf, в котором можно ввести в диалоговом окне один или несколько символов (рис. 9.14) и получить список людей, фамилии которых начинаются с этих символов (рис. 9.15).

    Рис. 9.14. Ввод первых символов фамилии для фильтрации записей


    Рис. 9.15. Отфильтрованные в сценарии FilterRecords.wsf записи


    Как и в сценарии SortRecords.wsf, символы в диалоговом окне вводятся с помощью VBScript-функции

    WSHInputBox()
    :

    //Выводим диалоговое окно для ввода первой буквы фамилии

    Res=WSHInputBox("Введите первые буквы фамилии", "Работа с базой данных");

    После этого формируется строка с нужным SQL-запросом (переменная

    SSource
    ) и строка с параметрами соединения с базой данных (переменная
    SConnect
    ):

    //Формируем шаблон, по которому будет производиться фильтрация

    SFilt="'"+Res+"%'";

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone WHERE (LastName LIKE "+SFilt+")";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    Создав объект

    Recordset
    (переменная
    RS
    ), мы присваиваем значение 3 свойству
    CursorType
    (это позволит узнать количество записей в наборе
    RS
    после выполнения SQL-запроса):

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Задаем статический курсор

    RS.CursorType = 3;

    //Открываем набор записей - результат запроса

    RS.Open(SSource, SConnect);

    //Определяем число записей в наборе

    RS_NomRecs = RS.RecordCount;

    Если в наборе RS не окажется ни одной записи (нет фамилий, начинающихся на нужные символы), то будет выведено соответствующее сообщение и произойдет выход из сценария:

    if (NomRecs==0) {

     WScript.Echo("В таблице Phone нет ни одной фамилии, начинающейся на '"+Res+"'");

     WScript.Quit();

    }

    Если же подходящие записи найдены, то они, как обычно, обрабатываются в цикле

    for
    . В результате формируется строка
    SOut
    со значениями полей
    LastName
    ,
    Name
    и
    Phone
    для этих записей:

    SOut="ВСЕГО "+NomRecs+" ЗАПИСЕЙ, НАЧИНАЮЩИХСЯ НА '"+Res+"':\n";

    //Перебираем все записи набора данных RS

    while (!RS.EOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+ RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к следующей записи

     RS.MoveNext();

    }

    В конце сценария объект

    Recordset
    закрывается, а строка
    SOut
    выводится на экран:

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    Полностью текст сценария FilterRecords.wsf приведен в листинге 9.6.

    Листинг 9.6. Фильтрация записей в таблице

    <job id="FiltRecs">

    <runtime>

    <description>

    Имя: FilterRecords.wsf

    Описание: Фильтрация записей таблицы Phone по первому символу

              фамилии

    </description>

    </runtime>

    <script language="VBScript">

    'Функция для реализации диалогового окна со строкой ввода

    'в сценариях JScript

    Function WSHInputBox(Message,Title)

    'Выводим диалоговое окно со строкой ввода

    WSHInputBox = InputBox(Message,Title)

    End Function

    </script>

    <script language="JScript">

    //Объявляем переменные

    var

     RS,       //Экземпляр объекта Recordset

     SSource,  //Текст SQL-запроса к БД

     SConnect, //Строка с параметрами соединения с БД

     SOut,     //Строка, в которой сохраняется выходная информация

     Res,      //Результат ввода в диалоговом окне

     SFilt,    //Шаблон, по которому будет производиться фильтрация

     NomRecs,  //Количество записей в отфильтрованном наборе

     s;

    //Выводим диалоговое окно для ввода первой буквы фамилии

    Res=WSHInputBox("Введите первые буквы фамилии","Работа с базой данных");

    //Формируем шаблон, по которому будет производиться фильтрация

    SFilt="'"+Res+"%'";

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone WHERE (LastName LIKE "+SFilt+")";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Задаем статический курсор

    RS.CursorType = 3;

    //Открываем набор записей-результат запроса

    RS.Open(SSource,SConnect);

    //Определяем число записей в наборе RS

    NomRecs = RS.RecordCount;

    if (NomRecs==0) {

     WScript.Echo("В таблице Phone нет ни одной фамилии, начинающейся на '" + Res+"'");

     WScript.Quit();

    }

    SOut="ВСЕГО "+NomRecs+" ЗАПИСЕЙ, НАЧИНАЮЩИХСЯ НА '"+Res+"':\n";

    //Перебираем все записи набора данных RS

    while (!RS.EOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к следующей записи

     RS.MoveNext();

    }

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    </script>

    </job>

    Перемещение в наборе записей 

    Во всех рассмотренных выше сценариях мы перемещались в наборе

    Recordset
    сверху вниз, от первой записи к последней. Существует, однако, возможность перемещаться по записям не только вперед, но и назад. Это осуществляется с помощью метода
    MovePrevious()
    , для использования которого нужно установить тип курсора (свойство
    CursorType
    ) в объекте
    Recordset
    равным 1, 2 или 3.

    Рассмотрим сценарий MoveInTable.js, в котором записи таблицы Phone выводятся в порядке, обратном физическому (рис. 9.16).

    Рис. 9.16. Записи таблицы Phone в обратном порядке


    Набор записей Recordset в этом сценарии открывается в режиме статической копии таблицы (свойство

    CursorType
    равно 3):

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Задаем статический курсор

    RS.CursorType = 3;

    После открытия набора записей мы переходим к последней записи с помощью метода

    MoveLast()
    :

    //Открываем набор записей - результат запроса

    RS.Open(SSource, SConnect);

    //Переходим на последнюю запись

    RS.MoveLast();

    После этого записи перебираются в цикле

    while
    :

    //Перебираем все записи набора данных RS

    while (!RS.BOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к предыдущей записи

     RS.MovePrevious();

    }

    Свойство

    BOF
    , используемое в цикле
    while
    , становится равным
    true
    , когда курсор будет находиться перед первой записью таблицы
    RS
    .

    После выхода из цикла объект

    Recordset
    закрывается и сформированная строка
    SOut
    выводится на экран:

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    Полностью текст сценария MoveInTable.js приведен в листинге 9.7.

    Листинг 9.7. Перемещение в наборе записей снизу вверх

    /*******************************************************************/

    /* Имя: MoveInTable.js                                             */

    /* Язык: JScript                                                   */

    /* Описание: Перемещение по набору записей в обратном порядке      */

    /*******************************************************************/

    //Объявляем переменные

    var

     RS,       //Экземпляр объекта Recordset

     SSource,  //Строка с текстом SQL-запроса к БД

     SConnect, //Строка с параметрами соединения с БД

     SOut,     //Строка, в которой сохраняется выходная информация

     s;

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect = "DSN=PhoneDS";

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Задаем статический курсор

    RS.CursorType = 3;

    //Открываем набор записей-результат запроса

    RS.Open(SSource,SConnect);

    //Переходим на последнюю запись

    RS.MoveLast();

    SOut="ВСЕ ЗАПИСИ ИЗ ТАБЛИЦЫ phone.dbf В ОБРАТНОМ ПОРЯДКЕ:\n";

    //Перебираем все записи набора данных RS

    while (!RS.BOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к предыдущей записи

     RS.MovePrevious();

    }

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    /*************  Конец *********************************************/

    Доступ к БД без создания DSN

    Напомним, что для получения доступа к базе данных мы предварительно создали DSN с именем PhoneDS (рис. 9.9). Однако связываться с базами данных можно и без описания DSN (DSN, Less Database Access). Для этого необходимо в качестве второго параметра метода

    Open
    объекта
    Recordset
    задать строку, в которой явно будут записаны название нужного драйвера и параметры соединения с базой. Для используемой нами базы данных DBF-формата достаточно указать каталог, в котором находятся нужные таблицы (этот параметр называется
    DefaultDir
    ). Например, если таблицы расположены в каталоге Tabl на диске С:, то строка
    SConn
    с параметрами соединения имеет следующий вид:

    SConn="Driver={Microsoft dBase Driver (*.dbf)};DefaultDir=C:\\Tabl";

    К положительным моментам доступа к данным без предварительного создания DSN можно отнести то, что строка соединения с базой формируется во время выполнения сценария (имя базы данных можно передавать в качестве параметра) — это позволяет писать более гибкие сценарии. Кроме этого, сценарий, не требующий предварительной настройки ODBC, легче переносить на другие машины. Недостаток этого подхода состоит в невозможности установить контроль над соединением с базой в той мере, в какой это позволяет сделать ODBC (это становится важным при работе с базой данных, находящейся в сети).

    В листинге 9.8 приведен сценарий DSN_Less.js, в котором доступ к таблице Phone осуществляется без использования DSN (предполагается, что файл Phone.dbf находится в текущем каталоге).

    Листинг 9.8. Доступ к базе Phone без использования DSN

    /*******************************************************************/

    /* Имя: DSN_Less.js                                                */

    /* Язык: JScript                                                   */

    /* Описание: Просмотр записей таблицы без использования DSN        */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell,    //Экземпляр объекта WshShell

     RS,          //Экземпляр объекта Recordset

     SSource,     //Строка с текстом SQL-запроса к БД

     SConnect,    //Строка с параметрами соединения с БД

     SOut,        //Строка, в которой сохраняется выходная информация

     SDefaultDir, //Путь к каталогу, в котором находится таблица Phone

     s;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Определяем путь к текущему каталогу, в котором хранится таблица Phone

    SDefaultDir=WshShell.CurrentDirectory;

    //Формируем SQL-запрос к таблице Phone

    SSource = "SELECT * FROM Phone";

    //Формируем строку с параметрами соединения с БД

    //(указываем нужный DSN)

    SConnect="Driver={Microsoft dBase Driver (*.dbf)};DefaultDir="+SDefaultDir;

    //Создаем объект Recordset

    RS=WScript.CreateObject("ADODB.Recordset");

    //Открываем набор записей-результат запроса

    RS.Open(SSource,SConnect);

    SOut="ВСЕ ЗАПИСИ ИЗ ТАБЛИЦЫ phone.dbf:\n";

    //Перебираем все записи набора данных RS

    while (!RS.EOF) {

     //Формируем строку со значениями трех полей, которые разделены

     //символами табуляции

     s=RS.Fields("LastName")+"\t"+RS.Fields("Name")+"\t"+RS.Fields("Phone");

     //В конце строки ставим символ перевода строки

     s+="\n";

     //Добавляем сформированную строку к переменной SOut

     SOut+=s;

     //Переходим к следующей записи

     RS.MoveNext();

    }

    //Закрываем объект Recordset

    RS.Close();

    //Выводим на экран строку SOut

    WScript.Echo(SOut);

    /*************  Конец *********************************************/









    Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное

    Все материалы представлены для ознакомления и принадлежат их авторам.