|
||||||||||||||||||||||||||
|
Глава 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
Определившись со структурой таблицы, запустим 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, язык структурированных запросов). Замечание
Вначале нам понадобится завести в системе 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); /************* Конец *********************************************/ |
|
||||||||||||||||||||||||
Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное |
||||||||||||||||||||||||||
|