|
||||||||||||||||||||||||||
|
Глава 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); /************* Конец *********************************************/ |
|
||||||||||||||||||||||||
Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное |
||||||||||||||||||||||||||
|