<<

стр. 7
(всего 10)

СОДЕРЖАНИЕ

>>

Сообщить(ОписаниеОшибки() ) ;
Возврат;
КонецПопытки;


// Создание объекта выполнения команды
Использование ADO 213

Command = Новый СОМОбъект("ADODB.Command");
// Указание активного соединения
Command.ActiveConnection = Connection;
// Определение текста команды
Command.CommandText = "INSERT INTO TestTable VALUES(20, 'Новая строка',
33.3, 44.4, 55.5)";
// Определение типа команды
Command.CommandType = 1;
// Выполнение запроса
Command.Execute();

// Закрываем соединение
Connection.Close();
Command = Неопределено;

Данный пример аналогичен примеру, приведенному в листинге 5.4, за ис-
ключением того, что в конструкции запроса INSERT нельзя указать имена
колонок.
Для чтения данных из листа Excel необходимо выполнить ряд стандартных
действий. Пример такой выборки приведен в листинге 5.18.

| Листинг 5.18. Чтение данных MS Excel средствами ADO
L^i^L; _—. :-i^_-_ :^j_L ^_._ -_--;_-__— ____i__. i._^_—. :_:_—..^_-_i_-.-._-l.^ „

// Чтение данных
// Создание объекта установки связи с источником данных
Connection = Новый СОМОбъект("ADODB.Connection");


// Подключение к источнику данных
Попытка
Connection.Open(СтрокаПодкгаочения);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки ;

// Создание объекта выполнения команды
Command = Новый СОМОбъект("ADODB.Command");
// Указание активного соединения
Command.ActiveConnection = Connection;
214 Глава 5
I/ Определение текста команды
Command.CommandText = "SELECT * FROM TestTable";
// Определение типа команды
Command.CommandType = 1;

// Создание объекта набора записей
RecordSet = Новый СОМОбъект("ADODB.RecordSet");
// Выполнение и получение набора данных
RecordSet = Command.Execute() ;

// Перебор данных
Пока RecordSet.EOF() = 0 Цикл
Сообщить("Строка: " + Recordset.Fields(1).Value);
Сообщить("Число: " + Recordset.Fields(4).Value);
RecordSet.MoveNext();
КонецЦикла;
(
// После того как набор записей уже не нужен, его следует закрыть
RecordSet.Close();
Connection.Close ();


Доступ к данным Microsoft Project
через OLE DB
Для доступа к данным Microsoft Project можно использовать объекты ADO.
Общие принципы, применяемые для доступа к данным MS Project, такие
же, что и для других источников данных, но есть некоторые особенности и
ограничения.
Некоторые аспекты использования средства доступа OLE DB для Microsoft
Project уникальны и должны быть приняты во внимание во избежание не-
желательных результатов.
П Существует четыре типа данных:
• text — текстовый;
number — ЧИСЛОВОЙ;

• boolean — логический;
• date — дата-время (в том виде, как они отображаются в интерфейсе,
например 27.12.1999 10:30).
Использование ADO 215

П Поля длительности возвращают число минут, умноженное на 10 (напри-
мер, 8 часов — это 4800), а поля трудозатрат — число минут, умножен-
ное на 1000 (8 часам соответствует 480 000).
П Даты, отображающиеся в интерфейсе как NA (нет данных), возвращают-
ся как значение о.
П Формула в настраиваемом поле, которая в интерфейсе привела бы к ре-
зультату #ERROR, возвращает значение по умолчанию для данного поля.
П Настраиваемое поле, для которого не установлено никакого значения,
возвращает значение, принимаемое по умолчанию.
G Поле индикатора настраиваемого поля в случае, когда индикатор не ус-
тановлен, возвращает значение -i.
П Значения трудозатрат для материальных ресурсов выражаются в едини-
цах, определенных в интерфейсе, а не числом минут, умноженным на 1000.
О Оператор SELECT без предложения WHERE возвращает пустые строки таб-
лиц ресурсов и задач. Если задать предложение WHERE, эти строки уже не
будут возвращены, даже если они подходят по всем остальным условиям.
В реализации средства доступа OLE DB для Microsoft Project 2002 действует
ряд ограничений.
П Не поддерживается доступ для чтения и записи.
П Не поддерживаются запросы сразу к нескольким таблицам. Для каждой
таблицы, к которой требуется доступ, необходимо использовать отдель-
ный запрос.
П Доступ к OLE DB осуществляется с помощью курсоров (наборов запи-
сей) последовательного доступа. Наборы записей с последовательным
доступом не поддерживают такие методы, как MovePrevious, MoveFirst
или MoveLast. Кроме того, наборы записей с последовательным доступом
не поддерживают использование свойства Recordcount.
П Объединения не поддерживаются, однако аналогичные возможности
предоставляют сформированные наборы записей, устанавливающие ра-
нее не существовавшие отношения между ключами, полями или набора-
ми строк. Можно также создавать иерархические наборы записей в таб-
личном формате.
П Не поддерживаются операторы — ANY, LIKE и is NOT.
П Не поддерживаются статистические функции — Sum, Avg, Min, мах, count
И StDev.

П Средство доступа OLE DB снабжено механизмом контроля времени, ко-
торый сигнализирует, когда следует выгружать файлы, но делает это не
раньше, чем произойдет событие загрузки. Если в поле TimeBeforeUnioad
установлено значение 1, то не проверяется — имеется ли открытый файл,
216 Глава 5

до попытки открыть другой. В итоге этот файл блокируется для чтения.
Во избежание возникновения данной ситуации надо создать фиктивный
файл, чтобы заставить средство доступа, после завершения работы над
текущим проектом, загружать некий несуществующий файл. Таким обра-
зом, файл, который был в работе, будет выгружен, а блокировка чтения
будет установлена на фиктивный файл.
Среда ADO обеспечивает доступ к OLE DB с использованием набора объек-
тов, событий, методов и свойств. Возможны два способа использования ADO:
П доступ к поставщику данных на локальном компьютере;
П доступ к поставщику с сервера Microsoft Project Server.
В листинге 5.19 показан доступ к файлу Microsoft Project на локальном ком-
пьютере, а также отображаются некоторые сведения о проекте.

нг 5.19. Подключение к проекту и вывод«

// Определение параметров соединения
Провайдер = "Microsoft.Project.OLEDB.10.О";
ИмяФайла = "C:\example.mpp";
// Если файл не защищен, то в строке подключения параметры
// User ID (пользователь) и Password (пароль) указывать не обязательно
Пользователь = " ;
"
Пароль = " ;
"

// Установка соединения с проектом
Попытка
Connection = Новый СОМОбъект("ADODB.Connection");
Connection.Open("Provider=" + СокрЛП(Провайдер) +
";Project Name=" + СокрЛП(ИмяФайла) +
";User ID=" + СокрЛП(Пользователь) +
";Password=" + СокрЛП(Пароль));
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;

// Запрос к проекту
Command = Новый СОМОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "SELECT * FROM Project";
217
Использование ADO


RecordSet = Новый СОМОбъект("ADODB.RecordSet");
,
RecordSet = Command.Execute();

// Получение свойств проекта
Название = RecordSet.Fields("ProjectTitle").Value;
ДатаНачала = RecordSet.Fields("ProjectStartDate").Value;
ДатаКонца = RecordSet.Fields("ProjectFinishDate").Value;

// Вывод свойств проекта
Сообщить("Название проекта: " + Название);
Сообщить("Дата начала: " + ДатаНачала);
Сообщить("Дата завершения: " + ДатаКонца);


В данном примере происходит подключение к файлу проекта
C:\example.mpp и выводится название проекта, даты начала и завершения
проекта из таблицы Project (проект). Эта таблица обеспечивает доступ к па-
раметрам уровня проекта.
Таблица Project имеет большое количество полей. Основные из них приве-
дены в табл. 5.4.

Таблица 5.4. Основные поля таблицы Project

Тип Описание
Имя поля
данных
Project (Проект) Название проекта, отображаемое как путь к
text
его расположению на диске, например
C:\example.mpp
ProjectUniqueID number Уникальный идентификатор проекта
(Уникальный идентифика-
тор проекта)
ProjectAuthor text Имя автора проекта. Используется для груп-
(Автор) пировки аналогичных проектов
ProjectCompany text Название организации, создавшей проект;
(Организация) используется для группировки аналогичных
проектов
ProjectCreationDate date Дата создания проекта
(Дата создания)
ProjectStartDate date Дата и время запланированного начала проекта
(Дата начала)
Дата и время запланированного завершения
ProjectFinishDate date
(Дата окончания) проекта
Глава 5
218

Таблица 5.4 (окончание)

Имя поля Тип Описание
данных
ProjectLastSaved date Дата последнего сохранения проекта
(Дата сохранения)
ProjectManager text Руководитель проекта. Используется для
(Руководитель) группировки проектов, имеющих одного руко-
водителя
ProjectRevision text Текущий номер версии файла проекта
(Версия)
ProjectSubject text Тема проекта. Используется для группировки
(Тема) аналогичных проектов
ProjectTitle text Название проекта. Используется для группи-
(Название) ровки аналогичных проектов


Все остальные поля таблицы Project и их типы можно вывести с помощью
объектов ADOX (листинг 5.20).




// Определение параметров соединения
Провайдер = "Microsoft.Project.OLEDB.10.0";
ИмяФайла = "C:\example.mpp";


// Начальная инициализация
Catalog = Новый СОМОбъект("ADOX.Catalog") ;
Catalog.ActiveConnection = "Provider=" + CoкрЛЩПровайдер) + ";Project
Name=" + СокрЛП(ИмяФайла); .


Table = Catalog.Tables.Item("Project");
// Выводим поля таблицы
Если Table.Columns.Count > 0 Тогда
Для НомерПоля = 0 По Table.Columns.Count-1 Цикл
Column = Table.Columns.Item(НомерПоля);
ИмяПоля = Column.Name;
ТипПоля = Column.Type;
ДлинаПоля = Column.DefinedSize;
Сообщить("Имя поля: " + ИмяПоля);
Сообщить("Тип поля: " + ТипПоля);
219
Использование ADO

Сообщить("Длина поля: " + ДлинаПоля);
КонецЦикла;
КонецЕсли;


Основная таблица, в которой хранятся сведения о задачах, включенных
в проект, имеет идентификатор — Tasks, основные поля которой перечис-
лены в табл. 5.5.

Таблица 5.5. Основные поля таблицы Tasks

Тип Описание
Имя поля
данных
TaskUniquelD number Уникальный идентификатор задачи
(Уникальный
идентификатор)
date
Tas kActual Start Дата и время фактического начала задачи
(Фактическое начало)
date
Tas kActual Finish Дата и время фактического завершения за-
(Фактическое дачи
окончание)
TaskActualWork number Объем трудозатрат, которые уже выполнены
(Фактические назначенными задаче ресурсами
трудозатраты)
date
TaskStart Дата и время запланированного начала выполне-
(Начало) ния задачи вычисляется автоматически, если у за-
дачи есть предшественник. TaskFinish — дата
и время запланированного завершения выпол-
нения задачи
TaskContact text Имя человека, являющегося ответственным за
(Контактное лицо) выполнение задачи
TaskName (Название) Название задачи
text
Введенные заметки о задаче
TaskNotes (Заметки) text
TaskOutlineLevel number Число, определяющее уровень задачи в иерар-
хической структуре проекта
(Уровень структуры)
TaskOutlineNumber text Точная позиция задачи в структуре. Например,
номер 7.2 означает, что данная задача являет-
(Номер в структуре)
ся второй подзадачей седьмой суммарной за-
дачи верхнего уровня
TaskPercentComplete number Текущее состояние задачи, выраженное в виде
завершенной части работы в процентах по от-
(Процент завершения)
ношению к общей длительности задачи
Глава 5
220

К задачам обычно привязан один или несколько ресурсов. В таблице
Assignments содержатся данные о необходимых ресурсах для выполнения
всех задач. Основные поля таблицы Assignments приведены в табл. 5.6.

Таблица 5.6. Основные поля таблицы Assignments

Тип Описание
Имя поля
данных

TaskUniquelD (Уникальный number Указатель на действительный идентифи-
катор в таблице Tasks
идентификатор задачи)
AssignmentUniquelD number Уникальный идентификатор назначения
(Уникальный идентификатор)
AssignmentResourcelD number Указатель на действительный идентифи-
(Идентификатор ресурса) катор в таблице Resources
AssignmentActualStart date Дата и время фактического начала на-
(Фактическое начало) значения
AssignmentActualFinish date Дата и время фактического завершения
(Фактическое окончание) назначения
AssignmentActualWork number Объем работы, которая уже выполнена
(Фактические трудозатраты) ресурсом задачи
AssignmentStart (Начало) date Запланированная дата и время начала
работы назначенного ресурса
AssignmentFinish date Запланированная дата и время заверше-
(Окончание) ния использования ресурса по задаче
AssignmentFinishVariance number Разница между датой окончания назначе-
(Отклонение окончания) ния по базовому плану и запланирован-
ной датой окончания
AssignmentNotes (Заметки) text Заметки о назначении
AssignmentUnits (Единицы) number Число единиц,' на которое ресурс назна-
чается задаче. Выражается в процентах
от максимального числа единиц ресурса
AssignmentWork number Общий запланированный объем трудоза-
(Трудозатраты) трат, которые ресурс должен выполнить
по задаче
AssignmentResourceName text Название ресурса, связанного с назначе-
(Название ресурса) нием
AssignmentResourceType number Тип ресурса: 0 — трудовой (люди и обо-
(Тип ресурса) рудование, назначается по умолчанию);
1 — материальный (расходные материа-
лы, например, сталь, бетон или грунт)
Использование ADO 221

Рассмотрим пример вывода дерева задач с указанием использованных ре-
сурсов для системы "1C:Предприятие" версии 8.0 (листинг 5.21).

Ш; 5.21. Вывод дерева задач с указанием использованных ресурсов'
. ..
,., ——..^-..„..-.....,.-гг-...-:-,........ —-р-;˜ Г"'----"' — —- """"""
]
стинг
| для версии 8.0

// Переводит номер задачи из формата ххх.хх.х в ххх.хх
Функция ПолучитьКодРодителя(Знач НомерЗадачи)
Числобхождений = СтрЧислоВхождений(НомерЗадачи, " " ;
.)
Поз = 0;
Если ЧислоВхождений = 0 Тогда
Возврат "О";
Иначе
Для Ном = 1 По ЧислоВхождений Цикл
Поз = Поз + Найти(Сред(НомерЗадачи, Поз +1), ".");
КонецЦикла;
Возврат Лев(НомерЗадачи, Поз - 1);
КонецЕсли;
КонецФункции


// Формирует дерево задач
Процедура СформироватьДерево()
Провайдер = "Microsoft.Project.OLEDB.10.0";
ИмяФайла = "C:\example.mpp";
Пароль = " ;
"


Состояние("Соединение с проектом. Пожалуйста ждите...");
Попытка
Connection = Новый СОМОбъект("ADODB.Connection");
Connection.Open("Provider=" + CoкрЛП(Провайдер) +
";Project Name=" + СокрЛП(ИмяФайла) +
";Password=" + СокрЛП(Пароль));
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;


// Запрос к задачам
Command = Новый СОМОбъект("ADODB.Command");
222 Глава 5

Command.ActiveConnection = Connection;
Command.CommandText = "SELECT
TaskName,TaskType,TaskUniquelD,TaskOutlineLevel,TaskOutlineNumber,
TaskStart,TaskFinish,TaskPercentComplete FROM Tasks";


RecordSet = Новый СОМОбъект("ADODB.RecordSet");
RecordSet = Command.Execute();


// Перебор данных
Пока RecordSet.EOF() = 0 Цикл
// Тип записи: 1-группа, 0-задача
ТипЗадачи = RecordSet.Fields("TaskType").Value;
// Имя задачи или группы
ИмяЗадачи = RecordSet.Fields("TaskName").Value;
// Уникальный идентификатор задачи или группы
ИдентификаторЗадачи = RecordSet.Fields("TaskUniquelD").Value;
// Уровень задачи
УровеньЗадачи = RecordSet.Fields("TaskOutlineLevel").Value;
// Номер задачи в формате хх.х.х
НомерЗадачи = RecordSet.Fields("TaskOutlineNumber").Value;
ДатаНачала = RecordSet.Fields("TaskStart").Value;
ДатаКонца = RecordSet.Fields("TaskFinish").Value;
ПроцентВыполнения = RecordSet.Fields("TaskPercentComplete").Value;


Если НомерЗадачи = 0 Тогда
СтрокаТПБазовая = ТабличноеПоле;
Иначе
// Поиск родительской задачи
Результат =
ТабличноеПоле.Строки.Найти(ПолучитьКодРодителя(НомерЗадачи),
"Ид", Истина);
Если Результат = Неопределено Тогда
СтрокаТПБазовая .= ТабличноеПоле;
Иначе
СтрокаТПБазовая = Результат;
КонецЕсли;
КонецЕсли;


// Добавляем параметры задачи в дерево
СтрокаТП = СтрокаТПБазовая.Строки.Добавить();
Использование ADO 223

СтрокаТП.Ид = НомерЗадачи;
СтрокаТП.Задача = ИмяЗадачи;
СтрокаТП.ДатаНачала = ДатаНачала;
СтрокаТП.ДатаКонца = ДатаКонца;


Ресурсы = " ;
"
Если ТипЗадачи = 0 Тогда // Это задача
// Запрос по ресурсам
Command = Новый СОМОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "SELECT AssignmentUnits,
AssignmentResourceName FROM Assignments WHERE AssignmentResourcelD >
0 AND TaskUniquelD = " + ИдентификаторЗадачи;

RecordSetResource = Новый СОМОбъект("ADODB.RecordSet");
RecordSetResource = Command.Execute();

// Перебор данных
Пока RecordSetResource.EOF() = 0 Цикл
ИмяРесурса =
RecordSetResource.Fields("AssignmentResourceName"). Value;
ПроцентЗагрузки =
RecordSetResource.Fields("AssignmentUnits"). Value * 100;
Ресурсы = Ресурсы + ?(Ресурсы="","","; ") +
СокрЛП(ИмяРесурса) + " ( + ПроцентЗагрузки + "%)";
"
RecordSetResource.MoveNext();
КонецЦикла;,

RecordSetResource.Close();
КонецЕсли;
СтрокаТП.Ресурсы = Ресурсы;
// Переход к следующей задачи
RecordSet.MoveNext();
КонецЦикла;
RecordSet.Close();
КонецПроцедуры

В данном примере подразумевается, что на форме обработки имеется эле-
мент — табличное поле с идентификатором табличноеполе. Это табличное
поле имеет четыре созданных на форме текстовых поля:
О ид — скрытое поле, предназначенное для хранения идентификатора задачи;
Глава 5
224

П задача — название задачи;
П датаНачала — запланированная дата начала выполнения задачи;
П датаКонца — запланированная дата окончания задачи;
П Ресурсы — строка, содержащая список используемых ресурсов и их за-
грузку.
Результат вывода дерева задач произвольного проекта показан на рис. 5.2.

i-r • Microsoft Project ADO Demo vl .0 © MAV 2004 _ПX

Имя Файла: | C:\eitample.mpp __ j-^|
OLEDB провайдер: [Microsoft.PrQiect.OLEDB.10.0


Дата начала : Дата окончания ^Ресурсы.
B-Deveioprnent 25.05.2004 9:00:00 20.07.2004 9:52:54
ф-Подготовительные действия 25.05.20049:00:00 03.06.200410:30:00
В-Разработка продукта 01.06.200416:44:59 20.07.20043:52:54
^•••Техническая реализация 01.06.200416:44:59 20.07.20049:52:54
| Анализ списка требова... 01.06,200416:44:59 03.06.200414:24:06 Михайлов (1002); Ко...;
| Разработка концептуал... 03.06.200414:24:06 06.06.20049:52:48 Михайлов (100%); Ко... \
' Разработатехническое, 06.06.20049:52:48 09.06.200415:22:48 Михайлов (100%}: Це...;
Разработка продукта 09.06.200415:22:48 06.07.200417:50:06 Центр разработок (1..J
Тестирование 06.07.200417:50:06 13.07.200411:06:30 Центр разработок П..Л
Ввод корректировок 13.07.200411:06:30 19.07.200415:22:54 Центр разработок (1...J
Создание поставки 19.07.200415:22:54 20.07.20049:52:54 Михайлов (50^); Цен... =
И-Разработка коммерческих... 02.06.200410:30:00 07.06.200413:44:59
В-Технологическая подготовка 09.06.2004 15:22:48 16.06.200415:22:48
1
Подготовка методологии 09.06.200415:22:48 16.06.200415:22:48 Михайлов (100Х);Це...;

Закрыть
Выполнить

Рис. 5.2. Результат вывода дерева задач проекта

Помимо основных, ранее описанных таблиц (project, Tasks и Assignments),
существуют и другие, не менее важные таблицы, подробное описание которых
в данной книге приводиться не будет. Рассмотрим их состав и назначение.
П Availability — таблица обычно используется вместе с таблицей для по-
лучения сведений о доступности ресурсов.
П BaseiineTaskSpiits — в этой таблице сохраняются базовые сведения
о прерывании для конкретной задачи.
П caiendarData и caiendarExceptions — в этих таблицах хранятся все кален-
дарные данные, имеющиеся в средстве доступа Microsoft Project OLE DB.
П Calendars — календари, используются для определения стандартного ра-
бочего и нерабочего времени. В проекте необходимо иметь один базовый
Использование ADO 225

календарь. У задач и ресурсов могут быть свои собственные календари,
но все они должны строиться на основе базового календаря. В этой таб-
лице хранятся основные календарные данные.
П CostRates — таблица обычно используется вместе с таблицей Resources
для отображения содержимого таблиц норм затрат, относящихся к ресур-
су. Кроме того, данную таблицу можно использовать совместно с табли-
цей Assignments для получения сведений о таблице норм затрат, исполь-
зуемой назначением.
П CustomFieidGraphicaiindicators — таблица обычно используется вместе
с таблицей CustomFieids для получения параметров настраиваемых по-
лей, для которых предусмотрены графические индикаторы.
П CustomFieids (настраиваемые поля) — данная таблица используется для
получения всех параметров настраиваемого поля. Для изменения этих
полей необходимо извлечь глобальный корпоративный шаблон.
П CustomFieidVaiueList — эта таблица используется для получения значе-
ний таблицы подстановок для настраиваемых полей, имеющих список
значений.
О CustomOutlineCodeFieids (поля кодов структуры) — в этой таблице со-
держится маска для каждой таблицы подстановки настраиваемого кода
структуры.
П GustomOutiineCodeLookupTabies (таблицы подстановки) — таблица дан-
ного типа используется для получения списка значений таблиц подста-
новки, связанных с полями настраиваемых кодов структуры.
П Predecessors (предшественники) — таблица обычно используется вместе
с таблицей Tasks для отображения подробных сведений о задачах-
предшественниках.
П Resources — в этой таблице содержатся сведения, относящиеся к ресурсам.
П Successors — таблица обычно используется вместе с таблицей Tasks для
отображения подробных сведений о задачах-последователях.
П TaskSpiits — в этой таблице хранятся даты начала и окончания преры-
вания задачи.
П WBS (структурная декомпозиция работ) — в этой таблице хранятся опре-
деления кода СДР, а также параметры кода СДР для проекта.




8 Зак. 722
Глава 6


Использование SQL-DMO
Понятие SQL-DMO
SQL-DMO (SQL Distributed Management Objects) — это предоставляемая
Microsoft SQL Server объектная модель, которая основана на СОМ-техно-
логии.
SQL-DMO скрывает детали структуры языка Transact-SQL и используется
при написании административных приложений и сценариев для Microsoft
SQL Server. Поставляемые с Microsoft SQL Server графические средства ад-
министрирования написаны с применением именно SQL-DMO, которая не
является моделью интерфейса данных и не применяется для написания
стандартных приложений баз данных.
SQL-DMO позволяет клиентскому приложению манипулировать такими
объектами базы данных, как таблицы, процедуры и свойства сервера через
интерфейс СОМ. Модель предоставляет приложению следующие возможности:
П управление таблицами (просмотр, создание, удаление, модификация);
П управление списком доступных серверов;
О управление правами доступа к серверам;
G управление списком баз данных на каждом сервере;
П управление сценариями таблиц базы данных;
П создание SQL-скриптов (таблиц, представлений, хранимых процедур,
пользователей и их ролей);
П выполнение SQL-запросов.
Для того чтобы объекты SQL-DMO можно было использовать на конкрет-
ном компьютере, необходимо установить на нем клиентскую часть Microsoft
SQL Server, который устанавливает библиотеку Microsoft SQL OLE Object
Library. Данная библиотека представляет собой ActiveX-интерфейс к объек-
там SQL-DMO. Посредством SQL-DMO можно получать данные из таблиц
SQL Server.
228 Глава 6
.

Особенно эффективно данную модель могут применять разработчики, ис-
пользующие Microsoft SQL Server Desktop Engine (MSDE), который постав-
ляется вместе с Access 2000. Этот сервер баз данных представляет собой
промежуточный вариант SQL Server и был создан специально для сопряже-
ния с более ранними версиями SQL Server. Хотя MSDE обладает меньшими
возможностями, чем SQL Server, он поставляется бесплатно в составе
Microsoft Office 2000. Однако версия MSDE, которая поставляется вместе
с Microsoft Office 2000, не включает Enterprise Manager. В результате пользо-
ватели MSDE не могут оценить все преимущества графического интерфейса
при управлении объектами базы данных.
В этой главе будут рассмотрены некоторые подходы к организации работы
с объектами SQL Server (далее — SQL-сервер) при помощи SQL-DMO.


Получение списка доступных серверов
Для получения атрибутов SQL-сервера предназначен объект SQLDMO. SQLServera.
В листинге 6.1 приведен пример вывода списка доступных серверов.

списка доступных серверов

Попытка
// Создаем объект SQLServer2
// SQLServer2 - предназначен для получения атрибутов MS SQL Server
oSQLServer2 = СоздатьОбъект("SQLDMO.SQLServer2");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;


oSQLServer2.LoginTimeout = 10;
oSQLServer2.ODBCPrefix = 0;


// Вывод имен общих SQL-серверов
ServerNameList = oSQLServer2.Application.ListAvailableSQLServers();
Для Ном = 1 По ServerNameList.Count Цикл
Сообщить(ServerNameList.Item(HoM));
КонецЦикла;


// Вывод локальных общих SQL-серверов
InstanceNameList = oSQLServer2.Listlnstalledlnstances();
Использование SQL-DMO 229

Для Ном = 1 По InstanceNameList.Count Цикл
Сообщить(InstanceNameList.Item(Ном)) ;
КонецЦикла;

В приведенном примере свойство oSQLServera. LoginTimeout предназначено
для определения числа секунд, во время которого будут происходить попыт-
ки подключиться. Свойство oSQLServera.ODBCPrefix управляет выводом
ошибок.


Перечисление спецификаций баз данных
Для того чтобы работать с объектами SQL-DMO, необходимо подключиться
к выбранному серверу (листинг 6.2).



// Создаем экземпляр объекта сервера и подсоединиться к нему
SQLServer = СоздатьОбъект("SQLDMO.SQLServer");
SQLServer.LoginTimeout = -1;


Попытка
Если ИспользоватьЫТАвторизацию = 1 Тогда
// Использовать авторизацию WinNT
SQLServer.LoginSecure = 1;
// При разрыве соединения - автоматически повторно не соединяться
SQLServer.AutoReConnect = 0;
// Подключение к серверу
SQLServer.Connect(ИмяСервера);
Иначе
// Использовать SQL Server авторизацию
SQLServer.LoginSecure = 0;
// При разрыве соединения - автоматически повторно не соединяться
SQLServer.AutoReConnect = 0;
// Подключиться с использованием SQL Security
SQLServer.Connect(ИмяСервера, СокрЛП(Пользователь), СокрЛП(Пароль));
КонецЕсли;
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
230 Глава 6

В приведенном примере после объявления объекта SQLServer, из библиоте-
ки SQL-DMO, программа генерирует экземпляр этого объекта и подсоеди-
няет его к серверу ИмяСервера. В листинге 6.2 приведена программа, реали-
зующая два варианта подключения к SQL-серверу — с помощью NT
авторизации, и без нее. Для соединения с SQL-сервером используется метод
connect, в который передается имя сервера, а в случае подключения с по-
мощью SQL Security, еще имя и пароль пользователя. Как правило, при
разработке с применением SQL-DMO необходимо пользоваться именем
пользователя и паролем, которые предоставляют широкие полномочия, по-
скольку SQL-DMO используется для программирования административных
функций.
При определении времени подключения к серверу в свойстве
SQLServer.LoginTimeout установлено значение -1, которое обозначает стан-
дартное время завершения по истечении 60 секунд.
После того как произошло соединение, можно вывести спецификации всех
существующих на сервере баз данных (листинг 6.3).

Листинг 6.3. Перечисление спецификаций баз данных

Для iCount = 1 По SQLServer.Databases.Count Цикл
// Выводим только НЕ системные БД
Если SQLServer.Databases.Item(iCount).SystemObject = 0 Тогда
ВазаДанных = SQLServer.Databases.Item(iCount);
Сообщить("База данных:" + БазаДанных.Name);
Сообщить("Дата создания:" + БазаДанных.CreateDate);
Сообщить("Количество таблиц:" + БазаДанных.Tables.Count);
Сообщить("Количество представлений:" + БазаДанных.Views.Count);
Сообщить("Количество процедур:" + БазаДанных.StoredProcedures.Count);
КонецЕсли;
КонецЦикла;

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

Получение списка таблиц и спецификаций полей
Чтобы получить доступ к спецификации каждой таблицы базы данных,
необходимо создать объект SQLDMO.Tabie, который позволяет манипулиро-
Использование SQL-DMO 231

вать со структурой конкретной таблицы. Элементы типа Table содержатся
в коллекции Database.Tables. Для того чтобы перебрать все элементы кол-
лекции, существует два способа. Первый — в цикле, с помощью метода
item, получать элементы коллекции, указывая в параметре порядковый но-
мер таблицы (листинг 6.4). Свойство Database.Tables.Count возвращает
количество таблиц в базе данных. Второй — с помощью конструкции
для каждого...из...Цикл...конецЦикла, которую можно использовать только в вер-
сии 8.0 системы "1С:Предприятие".




// Объект базы данных
Database = СоздатьОбъект("SQLDMO.Database");
Database = SQLServer.Databases(ИмяБазыДаных);


Для Ном = 1 По Database.Tables.Count Цикл
// Выводим только НЕ системные таблицы
Если Database.Tables.Item(Ном).SystemObject = 0 Тогда
Сообщить(Database.Tables.Item(Ном).Name);
КонецЕсли;
КонецЦикла;


В программном коде, показанном в листинге 6.4, выводятся имена всех таб-
лиц базы данных. С помощью свойства Systemobject объекта Table отсека-
ются системные таблицы.
Зная имена таблиц, можно получить спецификацию каждого ее поля — имя,
тип, длина поля, признак первичного ключа, признак возможности содер-
жать пустые значения. Для этих целей у объекта Table существует коллек-
ция columns, которая содержит сведения о каждом поле таблицы.
Рассмотрим пример, в котором, помимо имен таблиц, выводятся названия
полей и их спецификация (листинг 6.5).

дификации полей табг

// Объект базы данных
Database = СоздатьОбъект("SQLDMO.Database");
Database = SQLServer.Databases(ИмяБазыДаных);


// Объект таблица
Table = СоздатьОбъект("SQLDMO.Table");
232 Глава 6


Для Ном = 1 По Database.Tables.Count Цикл
// Выводим только НЕ системные таблицы
Если Database.Tables.Item(Ном).SystemObject = 0 Тогда
// Выводим имя таблицы
ИмяТаблицы = Database.Tables.Item(HoM).Name;
Сообщить("Имя таблицы:" + ИмяТаблицы);


Table = Database.Tables(ИмяТаблицы);
// Цикл по полям
Для НомерПоля = 1 По Table.Columns.Count Цикл
Column = Table.Columns.Item(НомерПоля);
Сообщить("Имя поля: " + Column.Name);
Сообщить("Тип данных: " + Column.DataType);
Сообщить("Длина данных: " + Column.Length);
Сообщить("Это первичный ключ: " + ?(Column.InPrimaryKey = -1,
" а , "Нет"));
Д"
Сообщить("Может принимать пустые значения: " + ?
(Column.AllowNulls = -1, "Да", "Нет"));
КонецЦикла;
КонецЕсли;
КонецЦикла;


Листинг 6.5 демонстрирует, как производится выборка элементов коллекции
таблиц Tables внутри базы данных. Объекты Table, в свою очередь, обладают
иерархически организованными коллекциями объектов и отдельными объек-
тами. Каждая таблица обязательно имеет коллекцию столбцов Columns, но
у любой таблицы может иметься единственный объект PrimaryKey, соответст-
вующий первичному ключу. Коллекция Keys ключей таблицы содержит ссыл-
ки на все ограничения первичного ключа таблицы и внешних ее ключей.
Объект Column имеет следующие основные свойства:
П Name — ИМЯ ПОЛЯ;

П DataType — строковое представление типа значений для поля (например,
varchar, int И Т. П.);

П Length — максимально допустимая длина значения;
П InPrimaryKey — признак первичного ключа (-1 — обозначает, что данное
поле является первичным ключом, о — нет);
П AllowNulls — признак возможности содержать пустые значения (-1 — поле
может принимать пустые значения, о — не может).
Использование SQL-ОЛЮ 233

Получение списка представлений
С помощью коллекции views объекта Database можно получить доступ
к представлениям, которые определены в базе данных. Для обхода элемен-
тов коллекции views можно воспользоваться все тем же свойством count,
которое возвращает общее количество представлений, и методом item, ко-
торый получает объект view (представление) по его номеру (листинг 6.6). Так
же допустим просмотр элементов коллекции с помощью конструкции
Для каждого...из...Цикл...КонецЦикла.




// Объект базы данных
Database = СоздатьОбъект("SQLDMO.Database");
Database = SQLServer.Databases(ИмяВазыДаных);


Для Ном = 1 По Database.Views.Count Цикл
// Выводим только НЕ системные представления
Если Database.Views.Itern(Ном).SystemObject = 0 Тогда
Сообщить(Database.Views.Item(HoM).Name);
КонецЕсли;
КонецЦикла;


Данный пример выводит список имен всех представлений базы данных.


Получение списка хранимых процедур
Получение списка хранимых процедур производится методом аналогичным
тому, который использовался и для таблиц. Исключением здесь является то,
что коллекция, которая содержит элементы свойств хранимых процедур,
называется storedProcedures (листинг 6.7).



// Объект базы данных
Database = СоздатьОбъект("SQLDMO.Database");
Database = SQLServer.Databases(ИмяБазыДаных);


Для Ном = 1 По Database.StoredProcedures.Count Цикл
// Выводим только НЕ системные процедуры
О Тогда
Если Database.StoredProcedures.Item(Ном).SystemObject
234 Глава 6

// Выводим имя хранимой процедуры
Сообщить(Database.StoredProcedures.Itern(Ном).Name);
КонецЕсли;
КонецЦикла;



Изменение структуры баз данных

Создание и удаление баз данных
Для добавления новой базы данных на SQL-сервер предназначен все тот же
объект SQLDMO.Database. При этом затрагиваются еще два дополнительных
объекта:
П SQLDMO.DBFile — объект физического файла базы данных;
П SQLDMO.LogFile — объект физического файла транзакций.
Для регистрации новой базы данных на сервере необходимо сначала создать
физический файл базы данных и файл транзакции.
Рассмотрим пример создания новой базы данных с именем NewDB (лис-
тинг 6.8).




// Объект базы данных
Database = СоздатьОбъект("SQLDMO.Database");
// Объект файла базы данных
DBFileData = СоздатьОбъект("SQLDMO.DBFile");
// Объект файла транзакций
LogFile = СоздатьОбъект("SQLDMO.LogFile");


// Имя новой БД
ИмяНовойБазыДанных = "NewDB";


// Установить имя новой БД
Database.Name = ИмяНовойБазыДанных;


// Определяем свойства файла БД
DBFileData.Name = ИмяНовойБазыДанных;
DBFileData.PhysicalName = SQLServer.Registry.SQLDataRoot + "\DATA\" +
ИмяНовойБазыДанных + ".mdf";
Использование SQL-DMO 235

DBFileData.PrimaryFile = 1;
DBFileData.Size = 2;
DBFileData.FileGrowth = 1;


// Добавим файл базы данных
Database.FileGroups("PRIMARY").DBFiles.Add(DBFileData);


// Определяем свойства файла транзакций
LogFile.Name = ИмяНовойБазыДанных + "Log";
LogFile.PhysicalName = SQLServer.Registry.SQLDataRoot + "\DATA\" +
LogFile.Name + ".Idf";
LogFile.Size = 2;


// Добавим файл транзакций базы данных
Database.TransactionLog.LogFiles.Add(LogFile);


// Создадим БД
Попытка
SQLServer.Databases.Add(Database);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;


Из приведенного выше кода видно, что сначала создаются объекты базы
данных Database, физического файла DBFiieData и файла транзакций
LogFile. Затем, С ПОМОЩЬЮ СВОЙСТВ Database. FileGroups ("PRIMARY") .DBFiles
И Database.TransactionLog. LogFiles, добавляются соответственно объекты
файла базы данных и файла транзакций. Только после этого база данных
регистрируется на сервере.
Рассмотрим основные свойства объекта DBFile.
О Name — имя файла.
П PhysicalName — физическое местонахождение файла.
П PrimaryFile — признак основного файла базы данных.
П s i z e — начальный размер файла в мегабайтах (необязательное свойство).
П FileGrowth — признак, определяющий, что необходимо хранить в базе
данных (таблицу, индекс, или регистрационные данные).
Рассмотрим основные свойства объекта LogFile.
П Name — ИМЯ файла.
Глава 6
26
3



238 Глава 6
Попытка
Database.Tables(ИмяТаблицы).Remove();
Исключение
КонецПопытки;


// Добавляем новую таблицу
Database.Tables.Add(Table);


Для определения типа данных и максимальной длины значения каждого
столбца используются соответственно свойства Datatype и Length. В коде,
представленном в листинге 6.9, например, столбец Prodio относится к типу
целочисленных данных int; столбец ProdName — к символьному типу дан-
ных переменной длины varchar.
Доступные типы данных представлены в табл. 6.1.

Таблица 6.1. Типы данных полей, доступные в SQL-DMO

Идентификатор Описание
bigint Целочисленный тип, от -263 (-9 223372 036854 775808)
до 263 (9 223372 036854 775807)
int Целочисленный тип, от-231 (-2 147 483 648) до 231 (2 147 483 647)
smallint Целочисленный тип, от 215 (-32 768) до 215 (32 767)
tinyint Целочисленный тип, от 0 до 255
bit Целочисленный тип, 0 или 1
decimal Тип с фиксированной точностью, от -1038 до 1038
numeric Эквивалентно типу decimal
money Денежный тип, от -263 (-922 337 203 685 477.5808)
до 263 (+922 337 203 685 477.5807)
smallmoney Монетный тип, от -214 748.3648 до +214 748.3647
float Числовой тип с плавающей запятой, до -1.79Е+308 по 1.79Е+308
real Числовой тип с плавающей запятой, от -3.40Е+38 до 3.40Е+38
datetime Дата и время, начиная с 1 января 1753 по 31 декабря 9999
с точностью до 3.33 миллисекунд
smalldatetime Дата и время, начиная с 1 января 1900 по 6 июля 2079 с точ-
ностью до одной минуты
char Строка фиксированной длины (не Unicode), максимально до-
пустимая длина — 8000 символов
Использование SQL-DMO 237

Table.FileGroup = "PRIMARY";


// Создаем колонки


// Добавить целочисленный тип данных
Columnl = СоздатьОбъект("SQLDMO.Column");
Columnl.Name = "ProdID";
Columnl.Datatype = "int";
Table.Columns.Add(Columnl);


// Добавить тип данных символьной строки
Column2 = СоздатьОбъект("SQLDMO.Column");
Column2.Name = "ProdName";
Column2.DataType = "varchar";
Column2.Length = 25;
Table.Columns.Add(Column2);


// Добавить еще один целочисленный тип данных
Columns = СоздатьОбъект("SQLDMO.Column");
Column3.Name = "Price";
ColumnS.DataType = "money";
Table.Columns.Add(ColumnS);


// Добавить десятичный тип данных
Column4 = СоздатьОбъект("SQLDMO.Column");
Column4.Name = "ProdWeight";
Column4.DataType = "decimal";
Column4.NumericPrecision = 9;
Column4.NumericScale = 5;
Table.Columns.Add(Column4);


// Очистить объекты
Columnl = " ;
"
Column2 = " ;
"
Columns = " ;
"
Column4 = " ;
"


// Перед добавлением новой таблицы в назначенную базу данных
// удалить предыдущую версию таблицы, если она существует
Глава 6
238

Попытка
Database.Tables(ИмяТаблицы).Remove();
Исключение
КонецПопытки;


// Добавляем новую таблицу
Database.Tables.Add(Table);


Для определения типа данных и максимальной длины значения каждого
столбца используются соответственно свойства Datatype и Length. В коде,
представленном в листинге 6.9, например, столбец Prodio относится к типу
целочисленных данных int; столбец ProdName — к символьному типу дан-
ных переменной длины varchar.
Доступные типы данных представлены в табл. 6.1.

Таблица 6.1. Типы данных полей, доступные в SQL-DMO

Идентификатор Описание
bigint Целочисленный тип, от -263 (-9 223372 036854 775808)
63
до 2 (9 223372 036854 775807)
int 31 31
Целочисленный тип, от-2 (-2 147 483 648) до 2 (2 147 483 647)
smallint Целочисленный тип, от 215 (-32 768) до 215 (32 767)
tinyint Целочисленный тип, от 0 до 255
bit Целочисленный тип, 0 или 1
decimal Тип с фиксированной точностью, от —1038 до 1038
numeric Эквивалентно типу decimal
money Денежный тип, от -263 (-922 337 203 685 477.5808)
до 263 (+922 337 203 685 477.5807)
smallmoney Монетный тип, от -214 748.3648 до +214 748.3647
float Числовой тип с плавающей запятой, до -1.79Е+308 по 1.79Е+308
real Числовой тип с плавающей запятой, от -3.40Е+38 до 3.40Е+38
datetime Дата и время, начиная с 1 января 1753 по 31 декабря 9999
с точностью до 3.33 миллисекунд
smalldatetime Дата и время, начиная с 1 января 1900 по 6 июля 2079 с точ-
ностью до одной минуты
char Строка фиксированной длины (не Unicode), максимально до-
пустимая длина — 8000 символов
Использование SQL-DMO 239

Таблица 6.1 (окончание)

Идентификатор Описание
varchar Строка переменной длины (не Unicode), максимально допус-
тимая длина — 8000 символов
text Строка переменной длины (не Unicode), максимально допус-
31
тимая длина — 2 (2 147 483 647) символов
nchar Строка фиксированной длины (Unicode), максимально допус-
тимая длина — 4000 символов
nvarchar Строка переменной длины (Unicode), максимально допусти-
мая длина — 4000 символов
ntext Строка переменной длины (Unicode), максимально допусти-
30
мая длина — 2 (1 073 741 823) символов
binary Двоичные данные фиксированной длины до 8000 байт
varbinary Двоичные данные переменной длины до 8000 байт
31
image Двоичные данные переменной длины до 2 (2 147 483 647) байт
cursor Ссылка на курсор
sql_variant Любой тип данных, поддерживаемый SQL Server
table Специальный тип данных, используемый в качестве хранили-
ща результата обработки данных
timestamp Уникальный номер в пределах базы данных
uniqueidentifier Глобальный уникальный идентификатор (GUID)


Как видно из приведенного примера, определение столбцов таблицы реали-
зуется в три этапа.
На первом этапе необходимо создать экземпляр столбца.
На втором — код должен настроить этот столбец, присвоив значения таким
его свойствам, как название Name и тип данных DataType. Определяемые
свойства могут меняться в зависимости от типа данных столбца. К примеру,
для столбца, принадлежащего целочисленному типу данных int, достаточно
настроить всего два свойства — имя и тип данных. В то же время столбец,
относящийся к типу данных varchar, требует определения значений как
минимум трех свойств — названия (Name), типа данных (DataType) и длины
(Length).
Третий этап создания столбца предусматривает инициирование метода до-
бавления Add, который и добавит созданный столбец в коллекцию столбцов
Columns рассматриваемой таблицы.
С помощью метода Database.Tables.Add происходит добавление таблицы
к подключенной базе данных. До начала добавления таблицы метод Remove
240 Глава 6

удаляет из базы данных все ранние версии этой таблицы. После этого код
вычищает все дочерние объекты.
Часть программного кода, отвечающая за установление соединения с серве-
ром, на котором будет размещена база данных, в примере не показана, так
как подразумевается, что подключение было совершено ранее, по аналогии
с кодом, приведенном в листинге 6.2.
Теперь рассмотрим пример создания таблицы заказов Orders (листинг 6.10).
У этой таблицы имеется первичный ключ, построенный по столбцу с акти-
визированным свойством идентичности identity. Приведенный пример
кода во многом напоминает код из листинга 6.9, за исключением перевода
свойства AiiowNuiis третьего столбца в состояние -1.




// Объект базы данных
Database = СоздатьОбъект("SQLDMO.Database");
// Объект новой таблицы
Table = СоздатьОбъект("SQLDMO.Table");


// Имя базы данных
ИмяБазыДанных = "TestDB";
// Имя новой таблицы
ИмяТаблицы = "Orders";


Database = SQLServer.Databases(ИмяБазыДанных)
Table.Name = ИмяТаблицы;
Table.FileGroup = "PRIMARY";


// Создаем колонки


// Добавить целочисленный тип данных
Columnl = СоздатьОбъект("SQLDMO.Column");
Columnl.Name = "OrderlD";
Columnl.Datatype = "int";
Columnl.AllowNulls = 0;
Columnl.Identity = -1;
Columnl.IdentitySeed = 1000;
Columnl.Identitylncrement = 10;
Table.Columns.Add(Columnl);
Использование SQL-DMO 241


// Добавить столбец со свойством Identity, который будет служить перигчным
ключом таблицы
Keyl = СоздатьОбъект("SQLDMO.Key");
Keyl.Name = "OrdersPK";
Keyl.Type = 1;
Keyl.Clustered = -1;
Keyl.KeyColumns.Add(Columnl.Name);
Table.Keys.Add(Keyl);


// Добавить временной тип данных datetime
Column2 = СоздатьОбъект("SQLDMO.Column");
Column2.Name = "OrderDate";
Column2.DataType = "datetime";
Table.Columns.Add(Column2);


// Добавить тип данных datetime, допускающий неопределенные значения
Column3 = СоздатьОбъект("SQLDMO.Column");
Column3.Name = "ShippedDate";
ColumnS.DataType = "datetime";
Columns.AllowNulls = -1;
Table.Columns.Add(ColumnS);


// Перед добавлением новой таблицы в назначенную
// базу данных удалить предыдущую версию таблицы,
// если она существует.
Попытка
Database.Tables(ИмяТаблицы).Remove();
Исключение
КонецПопытки;


// Добавляем новую таблицу •
Database.Tables.Add(Table);


// Очистить объекты
Columnl = " ;
"
Column2 = " ;
"
ColumnS = " ;
"
242 Глава 6

Код, приведенный в листинге 6.10, создает таблицу заказов с именем
Orders. Таблица orders содержит столбец идентификатора заказа orderio;
столбец orderDate, в который заносится дата ввода заказа, а также столбец
shippedDate, в который записывается дата отправки заказа. Столбец
Orderio служит первичным ключом таблицы, а столбец ShippedDate может
содержать неопределенные значения NULL. Чтобы заставить SQL Server авто-
матически формировать значения первичного ключа для новых строк, про-
цедура активизирует свойство identity, присваивая ему значение -1 (истина
или True). При этом исходное значение равно юоо, а приращение составля-
ет ю. После добавления в проект таблицы столбца со свойством identity
создается экземпляр Keyi ключевого объекта Key. Затем присваиваются зна-
чения свойствам Name и туре объекта Keyi, которые содержат соответствен-
но название и тип данных. Все возможные значения свойства туре объек-
та Key приведены в табл. 6.2.

Таблица 6.2. Типы ключей SQL-DMO

Значение
Константа SQL-DMO Описание

SQLDMOKey Foreign 3 Внешний ключ
1
SQLDMOKey Primary Первичный ключ
SQLDMOKey Unique 2 Уникальное поле, не допускающее значение
NULL
SQLDMOKey_Unknown О Ошибочное значение


Свойству Clustered объекта Keyi присваивается значение -1 (истина или
True). В результате уникальный индекс первичного ключа строится в виде
кластеризованного индекса для всей таблицы Orders. Прежде чем добавить
ключ кеу! в коллекцию ключей Keys таблицы Orders, необходимо указать
хотя бы один объект из класса столбцов, который будет поставлен в соот-
ветствие первичному ключу. В приведенном примере в этой роли выступает
столбец Orderio, у которого активизировано свойство identity.
Во все столбцы (листинг 6.9) и в два первых столбца (листинг 6.10) необхо-
димо вводить определенные значения. Иное дело третий столбец —
ShippedDate (листинге 6.10). В нем могут находиться неопределенные зна-
чения NULL, поскольку дата фактической отправки заказа неизвестна на мо-
мент ввода сведений о заказе. Она вводится в столбец shippedDate позднее,
когда заказ уже отправлен. Поэтому в третьем столбце присваивается значение
-1 свойству AiiowNuiis, после чего можно помещать в него неопределенные
значения. По умолчанию значение этого свойства равно о (ложь или False).
Таблица товаров Products (листинг 6.9) и таблица заказов orders (лис-
тинг 6.10) связаны между собой отношением "многие-ко-многим". Такое
Использование SQL-DMO 243

отношение имеет место потому, что один и тот же товар может войти в
один или несколько заказов, а каждый заказ может включать многие това-
ры. Чтобы отразить такое отношение в разрабатываемом проекте базы дан-
ных, необходимо внести в него два изменения. Во-первых, нужно переде-
лать проект таблицы товаров Products таким образом, чтобы у нее тоже
появился первичный ключ. Во-вторых, необходимо добавить в базу данных
новую таблицу, которая свяжет таблицы Products и orders. В этой таблице
будут храниться общие данные доменов обеих таблиц. К примеру, в ней
можно хранить количество определенного товара, которое указывается в от-
дельной строке заказа. Новую таблицу, которая связывает таблицы Products
И Orders, назовем OrderDetails.
В листинге 6.11 приведен пример создания таблицы связей OrderDetails.
У этой таблицы имеются внешние ключи, которые ссылаются на таблицы
Orders И Products.

истинг
OrderDetails
..
..
// Объект базы данных
Database = СоздатьОбъект("SQLDMO.Database");
// Объект новой таблицы
Table = СоздатьОбъект("SQLDMO.Table");


// Имя базы данных
ИмяБазыДанных = "TestDB";
// Имя новой таблицы
ИмяТаблицы = "OrderDetails";


Database = SQLServer.Databases(ИмяБазыДанных)
Table.Name = ИмяТаблицы;
Table.FileGroup = "PRIMARY";


// .Создаем колонки


// Добавить целочисленный тип данных
Coluranl = СоздатьОбъект("SQLDMO.Column");
Columnl.Name = "OrderID";
Columnl.Datatype = "int";
Table.Columns.Add(Columnl);
244 Глава 6
// Добавить целочисленный тип данных
Column2 = СоздатьОбъект("SQLDMO.Column");
Column2.Name = "ProdID";
Column2.DataType = "int";
Table.Columns.Add(Column2);


// Добавить внешний ключ, указывающий на таблицу Orders
Keyl = СоздатьОбъект("SQLDMO.Key");
Keyl.Name = "OrderIDFK";
Keyl.Type = 3;
Keyl.KeyColumns.Add(Columnl.Name);
Keyl.ReferencedTable = "Orders";
Keyl.ReferencedColumns.Add("OrderlD");
Table.Keys.Add(Keyl);


// Добавить внешний ключ, указывающий на таблицу Products
Кеу2 = СоздатьОбъект("SQLDMO.Key");
Key2.Name = "ProdlDFK";
Key2.Type = 3;
Key2.KeyColumns.Add(Column2.Name);
Key2.ReferencedTable = "Products";
Key2.ReferencedColumns.Add("ProdID");
Table.Keys.Add(Key2);


// Добавить первичный ключ, состоящий из двух столбцов
КеуЗ = СоздатьОбъект("SQLDMO.Key");
КеуЗ.Name = "OrderlDAndProdlDPK";
КеуЗ.Type = 1;
КеуЗ.Clustered = -1;
КеуЗ.KeyColumns.Add(Columnl.Name);
КеуЗ.KeyColumns.Add(Column2.Name);
Table.Keys.Add(КеуЗ);


// Добавить целочисленный тип данных
Column3 = СоздатьОбъект("SQLDMO.Column");
Column3.Name = "Quantity";
Columns.DataType = "int";
Использование SQL-DMO 245

Table.Columns.Add(ColumnS);


// Перед добавлением новой таблицы в назначенную
// базу данных удалить предыдущую версию таблицы,
// если она существует.
Попытка
Database.Tables(ИмяТаблицы).Remove();
Исключение
КонецПопытки;

// Добавляем новую таблицу
Database.Tables.Add(Table);

// Очистить объекты
Columnl = " ;
"
Column2 = " ;
"
Columns = " ;
"

Код, приведенный в листинге 6.11, показывает также синтаксис, применяе-
мый при построении первичного ключа на основе нескольких столбцов.
Код, создающий внешний ключ, начинается с генерации экземпляра объек-
та ключа Key. После присвоения имени этому объекту, его свойству туре
присваивается признак внешнего ключа (значение з). Вслед за этим добав-
ляется свойство Name объекта Key, содержащее название этого столбца,
в принадлежащую ключу коллекцию названий ключевых столбцов KeyCoiumns.
В соответствии со спецификацией столбец orderio таблицы orderDetails
назначается локальным столбцом внешнего ключа. Затем происходит назна-
чение таблицы orders и ее столбца Orderio соответственно таблицей и
столбцом, на которые будут формироваться ссылки. После настройки всех
этих свойств программный код, формирующий первый внешний ключ, за-
вершает свою работу добавлением созданного ключа в коллекцию ключей
Keys таблицы orderDetails. После этого создается внешний ключ, который
будет указывать на столбец идентификатора товара Prodio в таблице товаров
Products ИЗ столбца ProdID таблицы OrderDetails.
Часть кода, в которой описан объект кеуЗ, демонстрирует синтаксис, при-
меняемый для формирования первичного ключа из нескольких столбцов
таблицы. Этот блок операторов очень похож на те, в которых определяются
внешние ключи таблицы.
Для того чтобы удалить поле таблицы, необходимо воспользоваться методом
Column. Remove ( ) , где идентификатор Column является объектом удаляемого поля.
246 Глава 6

Создание SQL-скриптов
В листинге 6.4 был приведен пример получения списка таблиц, имеющихся
в базе данных. Аналогичным образом, через объект Database.Tables, можно
сгенерировать SQL-скрипт, который можно использовать для создания таб-
лиц в другой базе или на другом сервере.
В листинге 6.12 приведен пример генерации SQL-скрипта для создания таб-
лицы customers, находящейся в базе данных Northwind, входящий в постав-
ку продукта Microsoft SQL Server 7.0/2000.
—.....— ,.—. _ ...... ____._,_....,
.....—„„_
Листинг 6.12. Генерация SQL-скрипта создания таблицы Customers
базы данных Northwind

Database = СоздатьОбъект("SQLDMO.Database");
Database = SQLServer.Databases("Northwind");
// Выводим скрипт
Сообщить(Database.Tables.Item("Customers").Script());

SQL-скрипт, созданный в результате выполнения приведенного выше кода,
представлен в листинге 6.13.

! Листинг 6.13. SQL-скрипт создания таблицы Customers

CREATE TABLE [Customers] (
[CustomerlD] [nchar] (5) COLLATE Cyrillic_General_CI_AS NOT NULL ,
[CompanyName] [nvarchar] ( 4 0 ) COLLATE Cyrillic_General_CI_AS NOT NULL
[ContactName] [nvarchar] (30) COLLATE Cyrillic_General_CI_AS NULL ,
[ContactTitle] [nvarchar] ( 3 0 ) COLLATE Cyrillic_General_CI_AS NULL ,
[Address] [nvarchar] ( 6 0 ) COLLATE Cyrillic_General_CI_AS NULL ,
[City] [nvarchar] (15) COLLATE Cyrillic_General_CI_AS NULL ,
[Region] [nvarchar] (15) COLLATE Cyrillic_General_CI_AS NULL ,
[PostalCode] [nvarchar] (10) COLLATE Cyrillic_General_CI_AS NULL ,
[Country] [nvarchar] (15) COLLATE Cyrillic_General_CI_AS NULL ,
[Phone] [nvarchar] ( 2 4 ) COLLATE Cyrillic_General_CI_AS NULL ,
[Fax] [nvarchar] ( 2 4 ) COLLATE Cyrillic_General_CI_AS NULL ,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[CustomerlD]
) ON [PRIMARY]
) ON [PRIMARY]
GO
Использование SQL-DMO 247

<<

стр. 7
(всего 10)

СОДЕРЖАНИЕ

>>