16+
ComputerPrice
НА ГЛАВНУЮ СТАТЬИ НОВОСТИ О НАС




Яндекс цитирования


Версия для печати

Модуль поиска не установлен.

ADO, JSript, IE и MS Access

18.03.2003

Вячеслав Дукальский <mymess@yandex.ru>

Технология ADO (ActiveX Data Objects) была разработана Microsoft в 1998 году на основе OLE DB и решила несколько важных проблем - во-первых, предоставила унифицированный доступ к источникам данных разных типов (ODBC, таблицы Excell, базы Access и даже простые текстовые файлы) и, во-вторых, заметно упростила работу с ними. Тем не менее, основным источником данных для ADO остаются реляционные базы данных, поддерживающие структурированный язык запросов (SQL). Более подробную информацию вы сможете найти здесь: http://www.microsoft.com/data/ado.

Объекты ADO описаны в нескольких динамических библиотеках, которые можно найти в папке C:\Program Files\Common Files\SYSTEM\ADO. Это COM Dll, следовательно, поддерживающие различные языки программирования (VB, Java, C++, C#, JSscript & VBScript), правда, возможности и реализация в разных языках несколько отличаются. В этой статье мы рассмотрим примеры работы c базой Access, используя JavaScript и броузер Internet Explorer.

Скорее всего, в вашей системе уже будут установлены компоненты ADO, входящие в пакет Data Access Component. При необходимости скачайте его с http://www.microsoft.com/data/download.htm. При ручной установке вам необходимо скопировать Msado15.dll и Msadox.dll в C:\Program Files\Common Files\SYSTEM \ADO и зарегистрировать их в системе, выполнив regsrv32 Msado15.dll и regsrv32 Msadox.dll.

Давайте создадим базу данных в MS Access c именем testado.mdb в нашей рабочей директории. Измените пути в примерах к вашей базе данных (пути должны быть абсолютными).

В базе данных будет всего одна таблица users, которую мы создадим в режиме конструктора. Ниже приведены названия полей для этой таблицы и их типы данных:

Имя поля/Тип данных
ID/Счетчик
FirstName/Текстовый
LastName/Текстовый
Age/Числовой

Зададим ключевое поле ID и сохраним таблицу с именем users. Теперь внесем данные в эту таблицу. Данные можно вносить любые, но, разумеется, осмысленные. На этом подготовительный этап окончен, закроем Access и приступим к разработке скрипта для работы с нашей базой данных.

Создадим HTML-документ и сохраним его с именем sample_1.

Листинг sample_1.html.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Выборка данных из таблицы</title>
<script language="JavaScript">
<!--
// Создать элемент ActiveX объекта Connection
var Con = new ActiveXObject("ADODB.Connection")
// Запишем в переменную строку для подключения к базе данных
// Если вы используете Access'97, поменяйте значение Provider на Microsoft.Jet. OLEDB.3.51
var strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:/glr/ado_js/testado.mdb;";
// Создать элемент ActiveX объекта Command
var cmdUsers = new ActiveXObject ("ADODB.Command");
// Создать элемент ActiveX объекта Recordset
var rsUsers = new ActiveXObject("ADODB.Recordset");
// В эту переменную будет записан весь выходной html-код
var strHTMLOutput;
function getRecords()
{
try
{
// Создадим соединение
Con.Open(strCon);
// Создадим SQL-запрос
cmdUsers.CommandText = "SELECT * FROM users"; cmdUsers.ActiveConnection = Con;
rsUsers = cmdUsers.Execute();
strHTMLOutput = "<table><tr><th>ID</th><th>FirstName</th><th>LastName</th><th>Age</th></tr>";
while(!rsUsers.EOF)
strHTMLOutput += "<tr><td>";
strHTMLOutput += rsUsers("ID");
strHTMLOutput += "</td><td>";
strHTMLOutput += rsUsers("FirstName");
strHTMLOutput += "</td><td>";
strHTMLOutput += rsUsers("LastName");
strHTMLOutput += "</td><td>";
strHTMLOutput += rsUsers("Age");
strHTMLOutput += "</tr>";
rsUsers.MoveNext();
}
strHTMLOutput += "</table>";
Con.Close();
document.all.htmlOut.innerHTML = strHTMLOutput;
}
catch (e)
{
alert(e.message);
}
}
//-->
</script>
</head>
<body onload="getRecords()">
<div id=htmlOut></div>
</body>
</html>

Объявленные глобальные переменные в самом верху скрипта создают элементы ActiveX, и инициализируются объекты ADO.

В первую очередь нам необходимо создать объект Connection, который инициализирует обмен данными. Этот объект является базовым для объектов Command, Recordset и Error. Объект Command отвечает за SQL-запросы, a Recordset - за навигацию и управление полями данных. В переменной Con хранится объект ADO Connection, в cmdUsers - объект Command, в rsUsers - Recordset. Отслеживание ошибок будет вестись с помощью стандартной в таких случаях управляющей структурой try{} catch(...){}.

Объявим еще одну переменную strCon. В ней будет храниться строка для сооединения с базой данной. В значении Provider необходимо указать зарегистрированный в системе драйвер OLEDB. Если вы создавали базу в Access 2000, то значение Provider должно быть Microsoft.Jet.OLEDB.4.0, если в Access'97, то Microsoft.Jet.OLEDB.3.51. Путь к нашей базе testado.mdb необходимо задать абсолютный, измените значение Data Source на путь к вашей рабочей директории.

Кроме этого нам необходимо объявить еще одну переменную - strHTMLOutput для хранения нашего HTML-выхода с результатами запроса. В <BODY> мы добавили элемент <DIV> с индентификатором htmlOut. В дальнейшем с помощью свойства innerHTML мы будем выводить значение strHTMLOutput в этот тэг. Кстати, свойство innerHTML хотя и редко используется, но весьма полезное, позволяющее без перезагрузки страницы менять ее содержание, и поддерживается броузерами IE > 4 и последними "Нетскайпами". В IE это делается таким образом:

document.all.htmlOut.innerHTML = strHTMLOutput;

Создадим функцию getRecords, которая будет выбирать все значения из таблицы users и выводить в HTML-страницу. Вообще-то, совмещать в одной функции вид и представление - не самый хороший стиль программирования, желательно было бы вывести в разные функции выборку данных из таблицы и вывод их на экран, но чтобы не усложнять пример, ограничимся одной функцией.

В цикле try используем метод Open для создания соединения с базой данных. Присвоим объекту Command (хранится в переменной cmdUsers) SQL-запрос и затем, с помощью свойства ActiveConnection, укажем, к какому Connection относится этот объект Command. Далее с помощью метода Execute выполним запрос.

Выборка значений осуществляется в цикле while. Флаг EOF возвращает true, если все данные из результирующей таблицы выбраны. Осуществим конкатенацию строк для создания строки таблицы. После того как получим все данные из текущей строки результата запроса, переместим курсор на следующую строку с помощью метода MoveNext(). После выборки данных необходимо закрыть соединение с помощью метода Close().

Инициализируем функцию getRecords в <BODY onLoad="getRecords()"> и откроем эту страницу в IE. Результат должен быть следующим:

ID/FirstName/LastName/Age
1/Дмитрий/Петров/26
2/Анна/Петрова/22
3/Василий/Смирнов/27

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

Немного усложним пример и введем сортировку для каждого поля. Создадим файл sample_2 и скопируем в него все содержание из файла sample_1. Изменим функцию getRecords так, чтобы ее аргументом было имя сортируемого поля:

function getRecords(strField)
{
try
{
Con.Open(strCon);
cmdUsers.CommandText = "SELECT * FROM users ORDER BY " + strField;
cmdUsers.ActiveConnection = Con;
rsUsers = cmdUsers.Execute();
strHTMLOutput = "<table><tr><th>\
<a href="#" onClick = "getRecords('ID')">ID</a></th>
<th><a href=\"#\" onClick = \"getRecords('FirstName')\"> FirstName</a></th>\
<th><a href=\"#\" onClick = \"getRecords('LastName')\"> LastName</a></th>\
<th><a href=\"#\" onClick = \"getRecords('Age')\">Age</a></th></tr>";
while(!rsUsers.EOF)
{
strHTMLOutput += "<tr><td>";
strHTMLOutput += rsUsers("ID");
strHTMLOutput += "</td><td>";
strHTMLOutput += rsUsers("FirstName");
strHTMLOutput += "</td><td>";
strHTMLOutput += rsUsers("LastName");
strHTMLOutput += "</td><td>";
strHTMLOutput += rsUsers("Age");
strHTMLOutput += "</tr>";
rsUsers.MoveNext();
}
strHTMLOutput += "</table>";
Con.Close();
document.all.htmlOut.innerHTML = strHTMLOutput;
}
catch (e)
{
alert(e.message);
}

}

Обратные слешы при конкатенации позволяют игнорировать специальные символы - кавычки и невидимые символы начала новой строки, недопустимые в строчных значениях. В данном случае мы просто сортируем по возрастанию поля, имя которых передается через аргумент функции. При необходимости, можно ввести направления сортировки - по возрастанию или по убыванию (ASC или DEC).

Обращение к базе данных

посредством пользовательских SQL-запросов различного типа

При извлечении результата SQL-запроса, заданного пользователем, мы не можем напрямую использовать ту же схему, что и в предыдущих примерах, поскольку не знаем точно, какие поля таблиц должны быть отображены.

Например, если поменять SQL-запрос в нашей функции getRecords на такой: SELECT FirstName, LastName FROM users, мы получим ошибку, поскольку в результирующей таблице не будут найдены поля "ID" и "Age". Чтобы этого избежать, нам необходимо получить заголовки столбцов в таблице результата и затем перебрать в цикле их значения.

Чтобы узнать характеристики полей, необходимо обратиться к объекту Fields, наследуемого от Recordset (Запись). Каждый объект Fields соотносится с колонкой из объекта Recordset и имеет свойства:

- Name (имя поля) - возвращает имя поля.

- Value (значение) - устанавливает или возвращает значение поля.

- DefinedSize (заявленный размер) - максимальный размер поля, заявленный при создании базы данных.

- ActualSize (фактический размер) - фактический размер данных, хранящихся в поле.

- Precision (точность) - возвращает максимальное количество цифр (в байтах), используемых в текущем поле. Для объекта Fields это свойство открыто только для чтения.

- NumericScale (цифровая шкала) - аналогично свойству Precision, но возвращает максимальное количество цифр справа после запятой.

- Type (тип) - возвращает тип поля (свыше 30 различных вариантов).

В следующем примере нам потребуются первые два свойства объекта Fields:Name и Value и еще одно общее для различных объектов: Count - подсчет количества элементов.

Создадим новый файл и назовем его Sample_3.html. Скопируем в него весь код из предыдущего примера. Удалим функцию getRecords и создадим новую - query, в качестве аргумента получающую SQL-запрос:

function query(strSQL)
{
try
{
Con.Open(strCon);
cmdUsers.CommandText = strSQL;
cmdUsers.ActiveConnection = Con;
rsUsers = cmdUsers.Execute();
// Получаем кол-во полей
var nLen = rsUsers.Fields.Count;
strHTMLOutput = "<table><tr>";
// Создаем шапку таблицы
for(i = 0; i < nLen; i++)
{
strHTMLOutput += "<th>";
strHTMLOutput += rsUsers.Fields.Item(i).Name;
strHTMLOutput += "</th>";
}
strHTMLOutput += "</tr>";
// Если в переменной nLen 0 полей для отображения,
// то условие rsUsers.EOF выдаст ошибку,
// поэтому нужна дополнительная проверка
if(nLen != 0)
{
while(!rsUsers.EOF)
{
strHTMLOutput += "<tr>";
// Создаем строку таблицы
for(i = 0; i < nLen; i++)
{
strHTMLOutput += "<td>";
strHTMLOutput += rsUsers.Fields.Item(i).Value;
strHTMLOutput += "</td>";
}
strHTMLOutput += "</tr>";
rsUsers.MoveNext();
}
}
strHTMLOutput += "</table><p>Запрос выполнен</p>";
document.all.htmlOut.innerHTML = strHTMLOutput;
}
catch (e)
{
alert(e.message);
}
Con.Close();
}
Изменим тег <BODY>:
<body>
<form action="">
Ваш SQL-запрос:<br>
<textarea cols="30" rows="4"></textarea><br>
<input type="button" onclick="query(document.forms [0][0].value)" value="Выполнить"></form>
<div id=htmlOut></div>

В переменной nLen хранится количество полей результата. Мы получили это значение, используя свойство Сount. Далее мы создаем шапку таблицы результата с именами полей и затем непосредственно выводим сам результат запроса. Доступ к текущему полю осуществляется с помощью метода Item.

Попробуем теперь открыть этот файл. В текстовом поле потребуется ввести какой-нибудь SQL-запрос (любого типа). Давайте попробуем ввести запрос на вставку новых записей:

INSERT INTO users(FirstName, LastName, Age) VALUES('Дмитрий', 'Серов', 29)

Поскольку поле "ID" у нас имеет тип счетчик, его можно опустить (значение будет добавлено автоматически).

Теперь посмотрим, что у нас есть в таблице users:

SELECT * FROM users

Последней строкой, в результате, должна стоять добавленная нами запись.

Создание базы данных с использованием ADOX

ADOX является расширением программной модели ADO, включающей в себя объекты для создания схем и их модификации, а также механизмы поддержки безопасности. Все объекты ADOX собраны в динамическую библиотеку Msadox.dll, которой соответствует индентификатор "ADOX". Наиболее важные объекты ADOX представлены ниже:

- Catalog - содержит коллекцию объектов, описывающих источник данных.

- Column - колонка таблицы.

- Table - описывет таблицу базы данных.

- Key - ключевые поля.

В следующем примере мы создадим новую базу данных *.mdb не из Access, а с помощью написанного нами скрипта. Создадим новый файл Sample_4.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Создание базы данных с использованием ADOX.</title>
<script language="JavaScript">
<!--
var cat = new ActiveXObject("ADOX.Catalog");
var tb = new ActiveXObject("ADOX.Table");
// эти переменные свойств взяты из файла C:\Program Files\Common Files\SYSTEM\ADO\Adojavas.inc и
// описывают типы данных
var adInteger = 3;
var adVarWChar = 202;
// Новая база данных new_db.mdb
var srcDataSource = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:/glr/ado_js/new_db.mdb;"
function createDB()
{
try
{
// Создать базу
cat.Create(srcDataSource)
alert('База данных \"new_db.mdb\" создана!\nТеперь нажмите на \"Создать таблицу\"');
}
catch (e)
{
alert(e.message);
}

}
function createTbClients()
{
try
{
// Устанавливаем активное соединение с созданной нами базой данных
cat.ActiveConnection = srcDataSource;
// Описываем параметры новой таблицы
tb.Name = "Clients";
tb.Columns.Append("ClientID", adInteger);
tb.Columns.Append("CompanyName", adVarWChar, 50);
tb.Columns.Append("Phone",adInteger);
// Создаем таблицу
cat.Tables.Append(tb);
alert('Таблица \'Clients\' создана');
}
catch (e)
{
alert(e.message);
}

}
//-->
</script>
</head>
<body>
<a href="#" onclick="createDB()">Создать базу данных</a><br>
<a href="#" onclick="createTbClients()">Создать таблицу "Clients"</a>
</body>
</html>

Функция createDB() создает пустую базу данных. При вызове этой функции будет создана база данных в вашем рабочем каталоге (не забудьте поменять значение srcDataSource). После создания базы необходимо вызвать функцию createTbClients() для создания таблицы "Clients". Теперь можно открыть в Ассеss созданную нами базу данных new_db.mdb и просмотреть ее структуру.



статьи
статьи
 / 
новости
новости
 / 
контакты
контакты