    Глава 10 

    Работа с базами данных SQL 

    Марк Причард и Бшл Кертис 

    Хотя компоненты доступа к данным (ТТаЫе и TQuery) позволяют работать с 
удаленной SQL-базой данных точно так же, как и с локальной, есть некоторые 
тонкости, влияющие на быстродействие и возможности приложения. 
    Используя SQL-базы данных, вы получаете ряд новых возможностей, таких как 
запуск, хранимые процедуры, неявная обработка транзакций, а также массу 
проблем. Мы могли бы написать целую книгу о реализациях SQLбаз данных и их 
поддержке в Delphi, но тогда у авторов следующих глав возникли бы серьезные 
проблемы. Это, кроме того, было бы безвозвратной потерей вашего времени— вы 
наверняка уже выбрали подходящий SQLсервер и прилипли к нему намертво. Зачем 
же вам читать о функциональных возможностях SQL-сервера "XYZ", если вы 
используете SQL-сервер "ZYX"? 

    Что такое база данных SQL 

    Наиболее важный вопрос, на который вы сможете получить ответ сейчас, — 
каким образом Delphi поддерживает SQL-базы данных. Если это вам не интересно, 
перейдите к главе 12, "Использование генератора отчетов'', чтобы узнать всю 
подноготную о компонентах VCL, которые позволят вам легко истратить кучу 
бумаги для печати отчетов по базе данных, доставляя неописуемое удовольствие бухгалтерам. 
    Если вы все же решили ознакомиться с этой главой, перейдем к делу и точно 
определим, что означает термин SQL-база данных (SQL database). Под SQL обычно 
понимают Structured Query Language (структурированный язык запросов), т.е. 
набор операторов, связанных определенным образом. Этот набор делится на два 
поднабора.    ^ 

    —— Что такое база данных SQL 

    В этом разделе представлено введение в концепцию SQL-базы данных и описаны 
ее преимущества и недостатки. 

    —— Поддержка SQL-баз данных интерфейсом ВОЕ 

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

    ИВ Специальные возможности, связанные с SQL 

    Здесь речь идет о специальных функциональных возможностях компонентов 
ТТаЫе и TQuery, связанных с SQL, а также о компонентах, специально 
предназначенных для работы с SQLбазами данных, таких как TStoredProc И TUpdateSQL. 

    —И Особенности типов SQLсерверов 

    В этом разделе рассматриваются наиболее важные параметры BDE для каждого 
типа SQL-базы данных.                       1 

    271 

    •I Data Definition Language (Язык определения данных). Это превосходный 
пример компьютерного жаргона, поскольку этот язык представляет собой лишь 
набор операторов SQL, которые используются для определения и" Поддержки 
структуры вашей базы данных. ЯзыкТЗЙЬ включает возможности создания, 
корректировки и удаления баз данных, таблиц и полей, т.е. используется для 
описания способа хранения ваших данных. 
    • Data Manipulation Language (Язык обработки данных). Это поднабор 
операторов SQL, которые используются для обработки реальных данных в базе 
данных. Язык DML используется для добавления, корректировки и удаления данных 
в наборе таблиц базы данных. 
    Если вас интересует история SQL, найдите гуру, угостите его пивом и рыбой 
— и можете часами слушать его неторопливый лирический рассказ. 

    Щаметку 

    Определив понятие языка SQL, можно сделать вывод, что SQL-база данных — 
это база данных, взаимодействие с которой происходит с помощью языка SQL. Но 
давайте ненадолго отложим этот вопрос. Поскольку база данных и ее данные 
определяются языком, интерпретируемым во время выполнения, SQL-сервер должен 
обладать способностью разбираться в том, чего в действительности требуют 
SQL-операторы, написанные вами, а затем выполнить это. Такие 
высокоинтеллектуальные способности дают несколько преимуществ. 
    И Реализация локального файла не имеет значения. Вам не нужно ничего знать 
о формате файла базы данных на сервере. Сервер может сохранять данные в виде 
одной огромной электронной таблицы. 
    • Эффективность передачи данных. Передача набора физических данных между 
вашим приложением и сервером чрезвычайно эффективна — вы передаете запрос в 
виде операторов SQL серверу, а сервер возвращает только те данные, которые вас 
интересуют. Это особенно удобно в среде глобальной сети (Wide Area Network— 
WAN), где приложение клиента может быть соединено через: "медленную" 
коммутируемую линию.               ""'—— 
    • Скорость, скорость и еще раз скорость! Вы заметите, что время ответа 
SQL-сервера меньше, чем локальной базы данных, размещаемой на файл-сервере. 
Причина этого простая и может быть пояснена на следующем примере. Представьте 
себе, что вы хотите обновить значение пробега автомобиля из парка вашей 
компании. Если бы вы использовали локальную базу данных, файл-сервер передал 
бы индексный файл таблицы автотранспорта на вашу рабочую станцию, которая 
затем была бы обработана для определения местонахождения записи о интересующем 
вас автомобиле. Ваше приложение затем передало бы запрос на блокировку части 
таблицы, которая содержит нужную вам запись, а затем переслало бы сообщение 
для отмены блокировки. Работая с SQL-базой данных, вы просто пересылаете один 
оператор SQL длиной около 100 байт, а оставшаяся часть процесса происходит 
внутри сервера. 

    Знакомимся с SQL 

    Вы, может быть, будете удивлены, узнав, что собой представляет этот 
таинственный язык SQL. В этом разделе приводится пример, использующий образец 
базы данных InterBase, включаемый в инсталляцию Delphi 3. На некоторое время 
выйдите из среды Delphi — мы будем использовать утилиту Database Desktop, 
которая позволяет выполнять запросы, изменять структуру таблиц, а также 
выполнять всякого рода функции, связанные с базами данных. 

    Как открыть SQL-таблицу 

    Ниже перечислены действия, выполнив которые, можно загрузить утилиту 
Database Desktop и открыть таблицу в базе данных InterBase, предоставляемую в 
качестве образца. 
    1. В папке, в которой установлена утилита Database Desktop, дважды 
щелкните на пиктограмме утилиты. Появится диалоговое окно Database Desktop, 
показанное на рис. 10.1. 
    2. Выберите команду File^Open^Table, и появится диалоговое окно Open 
Table, показанное на рис. 10.2. 
    Чтобы открыть таблицу, можно воспользоваться кнопкой Open Table, 
расположенной на панели инстру[ Совет] ментов
    3. Выберите IDBLOCAL из раскрывающегося списка Alias и увидите диалоговое 
окно Database Information, показанное на рис. 10.3. 

    272                                     Часть III. Работа с базами данных 


    Рис. 10.1. Использование утилиты Database Desktop для манипуляций данными 
вне Delphi 

    Рис. 10.2. Диалоговое окно Open Table позволяет выбрать нужную таблицу 

    4. Введите имя пользователя и пароль. Если вы хотите войти под именем 
SYSDBA, то воспользуйтесь паролем masterkey. 
    5. Выберите таблицу employee (таблица служащих) и щелкните на кнопке Open. 

    Рис. 10.3. Диалоговое окно Database Information позволяет войти в базу 
данных SQLсервера 

    ок 

    С таблицей SQL в окне Database Desktop можно обращаться таким же образом, 
как и с локальной таблицей, т.е. ее можно просматривать, редактировать и 
преобразовывать. Есть лишь одно различие, на которое вы, может быть, обратили 
внимание. Указатель мыши принимает вид песочных часов, когда система BDE 
пересылает или выбирает данные. 

    Запросы SQL, созданные с помощью QBE 

    Сейчас, когда вы уже ознакомились с таблицей employee, создадим запрос 
SQL. Запрос, составленный в утилите Database Desktop с помощью QBE (Query By 
Example — запрос по образцу), конвертируется в SQL-запрос и передается 
SQL-серверу. Выполнив указанные ниже действия, вы создадите QBE-запрос для 
таблицы сотрудников, которая выводит имена и фамилии всех сотрудников, 
выполняющих работу третьей категории сложности. 
    1. Выберите команду File^New^QBD Query, и появится диалоговое окно выбора 
файла, которое очень похоже на диалоговое окно Open Table, показанное на рис. 10.2. 

    Совет I 
    Можно щелкнуть правой кнопкой мыши на кнопке панели инструментов Open 
Query и выбрать из контекстного меню команду New. 

    2. Выберите в раскрывающемся списке Alias значение IDBLOCAL. 
    3. Выберите таблицу служащих (employee) из списка и щелкните на кнопке 
Open. Появится новая форма QBE, как показано на рис. 10.4. 

    Рис. 10.4. С помощью QBE можно легко выполнять простые запросы по базе данных 


    Глава 10. Работа с базами данных SQL 273 

    4. Включите опции для полей FIRST_NAME и LAST_NAME. Под полями появятся 
флажки, указывающие, что эти поля будут включены в результирующую таблицу. 
    5. Щелкните в поле JOB_GRADE и введите число 3. 
    6. Воспользуйтесь командой Query^Run Query для выполнения запроса QBE. В 
результате появится таблица, содержащая 14 записей, удовлетворяющих запросу, 
как показано на рис. 10.5. 
    Предыдущий пример был тривиальным, но продемонстрировал, как легко 
конструировать запросы QBE. 

    Преобразование запросов QBE в SQL 

    Сформированный запрос QBE можно преобразовать в операторы SQL с помощью 
пары щелчков мышью. Выберите окно, содержащее ваш QBE-запрос, а затем 
выполните команду Query=>Show SQL. Появится окно SQL-редактора SQL Editor, 
показанное на рис. 10.6. 

    1 В SQL Ediloi :WORK:<Unli4ed> 

    Рис. 10.5. Результаты выполнения запроса возвращаются в виде другой таблицы 

    Рис. 10.6. Запрос SQL можно легко генерировать из запроса QBE 

    Как видите, язык SQL довольно прост, но все же требует изучения. К 
сожалению, разновидностей SQL столько же, сколько и SQL-серверов. Конечно, в 
одной книге невозможно описать все вариации языка SQL, так что используйте 
свои собственные возможности при изучении языка SQL. Есть много книг по SQL, а 
ваш SQL-сервер должен поставляться вместе с увесистыми томами по реализации 
языка на сервере. Кроме того, Delphi поставляется со справочным файлом 
(Localsql.hip), называемым Local SQL Guide, в котором документированы основы 
языка SQL. 

    Компоненты ТТаЫе, TQuery и SQL-базы данных 

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

    Когда использовать компоненты TTable и TQuery 

    Компоненты ТТаЫе и TQuery взаимодействуют с SQL-сервером по-разному, и 
каждый из них следует использовать в различных ситуациях. 

    Используйте компонент ТТаЫе в следующих случаях. 

    К Вы хотите использовать изменяемые данные (позволяющие редактирование) в 
экстенсивном режиме, таком, например, как при вводе исходных данных. 
    В Вы не хотите иметь дело с SQL, подключениями баз данных и их 
параметрами, а также вас не беспокоит небольшое снижение производительности. 

    274 Часть III. Работа с базами данных 


    Используйте компонент TQuery в следующих случаях. 

    • Необходимо выполнить большое количество изменений, удалений, простых 
запросов на изменение, а также сложных запросов на выборку. 
    • Необходимо выполнить DDL-оператор для изменения структуры таблицы. 

    Дополнительные функциональные возможности SQL 

    Компоненты ТТаЫе и TQuery поддерживают специфическое для SQL свойство 
UpdateMode, которое определяет, как система BDE идентифицирует обновляемую 
запись в многопользовательской среде. Это имеет значение в случае, когда 
другой пользователь может обновить запись, которую вы изменяете, прежде чем вы 
зафиксируете свои изменения. Свойство UpdateMode может принимать одно из трех значений. 
    • upWhereAll. Это значение является опцией ограничения и обеспечивает 
наилучшую защиту. Перед выполнением обновления система BDE сравнивает все поля 
в записи с теми, которые содержатся в буфере записи. Если поля отличаются, 
значит, другой пользователь модифицировал запись в то время, когда 
вашё"г1рйложение прочло запись и пыталось выполнить свою модификацию. В этом 
случае система BDE не позволит вашему приложению записать модифицированную 
запись в таблицу. 
    • upWhereKeyOnly. Это значение является наименее ограничивающим и наименее 
защищающим. При его установке система BDE проверяет изменение только ключевых 
полей. Если они не изменились, модификация разрешается. 
    • upWhereChanged. Это нечто промежуточное между значениями upWhereAll и 
UpWhereKeyOnly. При установке upWhereChanged система BDE проверяет изменение 
только тех полей, которые есть у вас во время проверки возможности выполнения 
модификации. Если другой пользователь изменил поле, которое вы пытаетесь 
модифицировать, ваше изменение будет проигнорировано. 

    Оптимизация скорости работы компонентов Ttable и TQuery 

    Размер результирующей таблицы, определяемый вашим оператором SQL, является 
основным фактором, влияющим на скорость выполнения этого оператора. Данный 
размер определяется путем умножения количества запрашиваемых полей на 
количество строк, которые удовлетворяют вашему запросу. Оба элемента являются 
объектами оптимизации, хотя методы различаются в зависимости от того, что вы 
используете — ТТаЫе или TQuery. 

    Уменьшение количества полей 

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

    Предварительная обработка полей, возвращаемых компонентом ТТаЫе 

    По умолчанию компонент ТТаЫе возвращает все поля таблицы. Используйте 
редактор полей (Field Editor) для включения только интересующих вас полей. Для 
этого дважды щелкните на компоненте ТТаЫе в проектировщике форм (Form 
Designer). Для добавления полей в редактор полей щелкните правой кнопкой в 
окне редактора и выберите Add Fields из контекстного меню. Это меню также 
предоставляет доступ к множеству функций, рассмотрение которых, к сожалению, 
выходит за рамки этой главы. 

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

    Уменьшение количества полей, возвращаемых компонентом TQuery, выполняется 
очень просто и происходит по умолчанию, поскольку, формируя запрос на языке 
SQL, при выборе полей вы можете включить лишь поля, которые вам требуются. И 
еще одно замечание— избегайте использования оператора SELECT *, поскольку вряд 
ли вам потребуется, чтобы возвращались все поля. 

    Уменьшение количества записей 

    Уменьшить количество записей в результирующей таблице значительно труднее, 
чем уменьшить количество полей. 

    Глава 10. Работа с базами данных SQL                                 275 


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

    Компонент ТТаЫе по уомолчанию возвращает все записи таблицы. Чтобы 
ограничить набор записей, используют свойство Fikter,"Fiitered или 
FilterOptions, событие 0'п'ЕПТег или метод SetRange. В системе электронной 
справки эти средства описаны достаточно полно, а пример использования метода 
SetRange приведен в главе 9, "Работа с локальными базами данных". 

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

    Чтобы ограничить количество записей, возвращаемых компонентом TQuery, 
нужно просто более точно сформулировать критерий отбора. Чем больше вы 
ограничите размеры результирующего набора, тем меньше данных нужно будет 
пересылать серверу по сети и тем меньше будет время реакции сервера на запросы 
других пользователей. 

    Компоненты доступа к данным 

    Компонент TDatabase 
    Компонент TDatabase предоставляет дополнительные возможности для контроля 
соединения с SQL-базой данных через различные свойства, методы и события. 

    Свойства компонента TDatabase 

    Компонент TDataBase располагает несколькими свойствами, позволяющими 
выполнить настройку компонента. 
    Свойства AliasName и DatabaseName 

    Эти свойства идентифицируют базу данных, к которой подключен компонент 
TDataBase. Для указания псевдонима существующей BDE-базы данных используйте 
свойство AliasName, а для указания временного, связанного с приложением, 
псевдонима используйте свойство DatabaseName. В следующем фрагменте программы 
устанавливается связь с базой данных IBLOCAL и создается псевдоним для 
приложения, который называется employee. В этом фрагменте используется 
компонент dbTest класса TDataBase. 

    with dbTest do begin 
    { Закрываем базу данных. } 
    Close; 
    ( Устанавливаем новый псевдоним и имя базы данных. } 
    AliasName := 'IBLOCAL'; 
    DatabaseName := 'EMPLOYEE'; 
    { Открываем базу данных. } 
    Open; 
    end; 


    Свойство KeepConnection 

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

    Свойства LoginPrompt и Params 

    Свойство LoginPrompt определяет, будет ли запрашиваться имя пользователя и 
пароль при каждой установке связи с базой данных. Если установить его равным 
True, то для запроса пароля и имени пользователя будет появляться диалоговое 
окно, показанное на рис. 10.3. Если установить его равным False, то имя 
пользователя и пароль будут браться из свойства Params компонента TDatabase. 
Ниже приведен пример использования этих свойств. 

    with dbTest do 
    begin 
    { Установка имени пользователя и пароля для свойства Params. ) 
    Params.Add('username=sysdba'); 
    Params.Add('password=masterkey'); 


    276                                     Часть III. Работа с базами данных 


    { Отключаем запрос при входе. } 
    LoginPrompt := False; 
    { Открываем базу данных. } 
    Open; 
    end; 


    Свойство Translsolation 

    Свойство Translsolation определяет степень изоляции между выполняемыми 
транзакциями и базой данных. Свойство может принимать одно из трех следующих значений. 
    • tiDirtyRead. Установка такого значения приводит к тому, что система BDE 
возвращает текущее значение записи, даже если изменения не были зафиксированы 
на диске. Эта установка отражает текущее состояние базы данных для вашего 
приложения наиболее точно и наименее надежно, так как данные, которые вы 
прочли, могут измениться, если вы вызовете метод Rollback во время выполнения 
транзакции.                      ""'"""""—•— 
    • tiReadConnnited. При этом значении возвращаются только такие изменения, 
которые были зафиксированы. 
    • tiRepeatableRead. Такое значение свойства Translsolation приводит к 
тому, что для записи в течение всей транзакции возвращаются только 
первоначальные значения полей. 
    В следующей таблице показаны различные точки в определенной транзакции, в 
которых значения для свойства Translsolation приводят к тому, что система BDE 
возвращает изменения в записи. 

    Точка в транзакции                 Доступность измененных данных 
    Начало транзакции                   — 
    Модификация записи                 tiDirtyRead 
    Фиксация записи                     tiReadCommited 
    Конец транзакции                    tiRepeatableRead 


    Методы компонента TDatabase 

    Компонент TDataBase содержит следующие методы, позволяющие 
взаимодействовать с базой данных. 
    • Open и Close. Метод Open подключает приложение к базе данных, а метод 
Close, напротив, отключает от нее. Свойство Connected имеет значение True, 
когда связь установлена, и False, когда ее нет. 
    B CloseDatasets. Метод CloseDatasets закрывает все наборы данных в вашем 
приложении, которые используют конкретную базу данных. Этот метод применяется 
перед выполнением функции, требующей монопольного доступа к базе данных. 
    1 StartTransaction, Commit и Rollback. Эти методы используются для явного 
управления транзакциями и подробно описаны в главе 9, "Работа с локальными 
базами данных". 

    События TDatabase 

    Компонент TDataBase имеет лишь одно^обь1тие^ОпЬод1п. Оно возникает перед 
установлением связи с базой данных и позволяет изменить свойство Params. 
Пример использования этого свойства приведен выше в этой главе, в разделе 
"Свойства LoginPrompt и Params". 

    Редактор базы данных 

    Редактор базы данных (Database Editor), показанный на рис. 10.7, 
запускается с помощью двойного щелчка на компоненте в проектировщике форм и 
позволяет задать параметры компонента TDataBase. 

    Компонент TStoredProc 

    Компонент TStoredProc используется для выполнения процедур, хранящихся на 
SQL-сервере. Эти процедуры могут возвращать набор данных для редактирования, 
изменять поле, модифицировать структуру таблицы, т.е. выполнять все то, что вы 
можете сделать на языке SQL. Хранение и выполнение процедур на сервере дает 
следующие преимущества. 
    в Централизация логики базы данных. С помощью создания хранимых процедур 
можно определить логику или бизнес-правила для наших данных в наиболее 
подходящем месте — в базе данных. Это означает, что все приложения, которым 
требуются функциональные возможности хранимых процедур, могут найти их в одном 
предопределенном месте. 


    Глава 10. Работа с базами данных SQL                                 277 


    Рис. 10.7. Используйте редактор баз данных для установки свойств 
компонента TDataBase 

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

    Свойства 

    Компонент TStoredProc предоставляет несколько свойств, с помощью которых 
можно настраивать конфигурацию объекта и влиять на его поведение. 

    Свойства DatabaseName и StoredProcName 

    Эти свойства идентифицируют хранимую процедуру, расположенную на сервере. 
В следующем фрагменте программы конфигурируется компонент spDaily класса 
TStoredProc для запуска хранимой процедуры DailyProcessing для базы данных Finance. 

    with spDaily do 
    begin 
    f Устанавливаем имя базы данных. } 
    DatabaseName := 'Finance'; 
    { Устанавливаем имя хранимой процедуры. } 
    StoredProcName := 'DailyProcessing'; 
    end; 


    Свойства Params, ParamCount, ParamByName и ParamBindMode 

    Эти свойства используются для передачи параметров между вашим приложением 
Delphi и хранимой процедурой. Свойства Params, ParamCount и ParamByName 
подобны свойствам компонента TQuery и описаны в главе 9, "Работа с локальными 
базами данных". 
    Свойство ParamBindMode определяет, как ваши параметры связаны с 
параметрами, ожидаемыми хранимой процедурой. Если вы установили значение 
свойства равным pbByName, система BDE будет использовать имена параметров. 
задаваемые в компоненте TStoredProc, для их сравнения с теми, которые 
определены в хранимой процедуре. Это удобно при указании параметров в порядке, 
отличном от порядка, ожидаемого хранимой процедурой. Если вы установили 
значение свойства ParamBindMode равным pbByNumber, система BDE будет 
использовать порядковые номера параметров для связи элементов, задаваемых 
компонентом TStoredProc, с теми, которые определены хранимой процедурой. Такой 
способ удобен, если список параметров взят из другого источника, который 
определил другие имена для того же самого набора параметров (например, с 
помощью метода CopyParams).                  '~" """ 

    Методы компонента TStoredProc 

    Компонент TStoredProc объявляет несколько методов, которые используются 
для манипулирования объектом во время выполнения. 

    278 Часть III. Работа с базами данных 


    Методы Prepare, ExecProc, Open и Close 

    Эти методы управляют основным состоянием хранимой процедуры. Метод Prepare 
готовит хранимую процедуру к выполнению с помощью метода ExecProc или Open. 
Метод ExecProc используется, когда процедура должна возвратить одну запись, а 
метод Open применяют при возврате набора данных, содержащего несколько 
записей. Метод Close просто закрывает компонент TStoredProc и устанавливает 
его свойство State в состояние dslnactive. В следующем фрагменте программы 
выполняется хранимая процедура Ла11уРгосе5$и^для базы данных Finance. 

    with spDaily do 
    begin 
    { Устанавливаем имя базы данных и хранимой процедуры. } 
    DatabaseName := 'Finance'; 
    StoredProcName := 'DailyProcessing'; 
    { Готовим хранимую процедуру к выполнению. } 
    Prepare; 
    { Выполняем хранимую процедуру. } 
    ExecProc; 
    end; 


    События компонента TStoredProc 

    |      Компонент TStoredProc содержит тот же набор событий, что и 
компоненты TTable и TQuery (глава 9, "Работа с локальными базами данных"). 

    Компонент TUpdateSQL 

    Компонент TUpdateSQL используется для кэширования изменений в наборах 
данных SQL. Типичным его применением является разрешение модификации 
набороТГдаПньЕхТТфедназначенных только для чтения и не соответствующих 
ограничениям для изменяемых запросов. Компонент TUpdateSQL также может 
использоваться для предоставления дополнительной защиты, если применяются 
изменения к таблице, доступной через компонент TTable. 
    Свойство UpdateObject компонентов TTable или TQuery подключает их к 
компоненту TUpdateSQL, который модифицирует лежащий в основе набор данных. 
Компонент TUpdateSQL выполняет эти функции путем предоставления нескольких 
свойств и методов. 

    Свойства 

    Наибольший интерес представляют свойства DeleteSQL, InsertSQL и ModifySQL, 
которые содержат операторы SQL для удаления, вставки и модификации набора данных. 
    Свойства SQL добавляет трехэлементный перечислимый индекс для разделения 
трех операторов SQL. Этими перечислимыми значениями являются ukDelete, 
uklnsert и ukModify, которые относятся к соответствующим свойствам. Например, 
оба следующих примера назначают один и тот же список TStrings для элемента 
управления ibSQL класса TListBox. 

    { Назначаем оператор SQL для удаления в списке TListBox. ) 
    ibSQL.Clear; 
    ibSQL.Items.Assign(usCust.DeleteSQL) ; 

    и 

    { Выполняем те же самые назначения с помощью свойства SQL. } 
    ibSQL.Clear; 
    ibSQL.Items.Assign(usCust.SQL[ukDelete]) ; 

    В этих фрагментах используется компонент usCust класса TUpdateSQL. 

    Методы компонента TUpdateSQL 

    В классе TUpdateSQL содержится три важных метода. 
    • SetParams заменяет параметры, указанные в операторе SQL, теми, которые 
используются при обновлении. 
    В ExecSQL выполняет оператор SQL, который обновляет набор данных. 
    • Apply впервые вызывает метод SetParams для установки оператора и его 
выполнения с помощью вызова метода ExecSQL. 

    Глава 10. Работа с базами данных SQL                                 279 


    Особенности типов SQL-серверов 

    В этом разделе представлен дополнительный материал и советы по увеличению 
производительности вашего SQLсервера. 

    Транзакции в базах данных SQL 

    В главе 9, "Работа с локальными базами данных", вводится понятие 
транзакции — метода, гарантирующего целостность базы данных в случае сбоя. Эта 
концепция реализуется явной транзакцией путем использования методов 
StartTransaction, Commit и Rollback, объявляемых классом TDatabase. 
    В SQL-серверах вводится неявная транзакция — на каждый оператор SQL, 
который вы выполняете, распространяется защита, восстанавливающая базу данных 
в случае сбоя. Это не требует с вашей стороны никакого кодирования, хотя 
управление явными транзакциями является более гибким. 

    Использование параметров в SQL 

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

    procedure SearchForOrders(dtSearch : TDateTime); 
    var sDate : String; 
    begin 
    { SQL требует даты в формате mm/dd/уууу. } 
    sDate := FormatDateTime('imn/dd/yyyy',dtSearch); 
    with qrySearch do 
    begin 
    { Очищаем текущий оператор SQL. } 
    SQL.Clear; 
    { Добавляем новый оператор SQL. } 
    SQL.Add('select OrderNum from STOCK'); 
    SQL.Add(Format('where OrderDate'' > %s''',[sDate]) ; 
    ( Выполняем запрос. } 
    Open; 
    end; 
    end; 

    Кроме того, что подобный код является избыточным, его еще довольно трудно 
поддерживать в разных областях применения вашего приложения. Используя 
параметры, можно построить оператор SQL во время проектирования, а затем 
задать значение даты как параметр во время выполнения. Для определения 
параметра нужно просто поставить двоеточие перед именем параметра, как 
показано в следующем операторе SQL: 

    select OrderNum from STOCK where OrderDate > :P_OrderDate 

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

    ззмбтку 
    
    Р_. Это будет гарантировать, что имя вашего параметра не совпадет с именем 
поля, а код приобретет дополнительную внутреннюю документированность. 
    После ввода оператора SQL в свойство SQL объекта TQuery Delphi заполняет 
массив свойств Params именами ваших параметров, а затем устанавливает свойство 
ParamCount равным количеству элементов в массиве. Однако, прежде чем присвоить 
значение параметру, следует назначить тип этому параметру. Для того чтобы это 
сделать, нужно отредак

    280                                     Часть III. Работа с базами данных 

    тировать свойство Params объекта класса TQuery в окне Object Inspector. С 
помощью этого средства выводится диалоговое окно Parameters, показанное на 
рис. 10.8. 
    Теперь, когда мы присвоили имена параметрам и указали их тип, можно 
задавать для них значения при выполнении приложения. В следующем фрагменте 
программы используются параметры для реализации поиска заказов, как в 
предыдущем примере. 

    procedure SearchForOrders(dtSearch : TDateTime); 
    begin with qrySearch do 
    begin 
    { Присваиваем значение параметру. } 
    ParamByName('P_OrderDate').AsDateTime := dtSearch; 
    { Выполняем запрос. } 
    Open; 
    end; 
    end; 

    Рис. 10.8. Используйте диалоговое окно Parameters для установки типов 
параметров во время проектирования 

    В этом примере подразумевается, что в SQL-операторе определен параметр 
P_OrderDate и ему присвоен тип DateTime. Вы, может быть, обратили внимание на 
использование метода ParamByName. Он подобен методу FieldByName — позволяет 
указать параметр с помощью его имени, а не через индекс в массиве Params. 

    Советы по увеличению производительности 

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

    Увеличение производительности путем настройки параметров BDE 

    Программа BDE Administrator позволяет установить следующие опции, которые 
увеличат скорость взаимодействия с SQL-сервером. 
    • Опции кэширования схемы. Схема содержит структуру таблиц и полей в базе 
данных. Кэширование схемы позволяет системе BDE сосредоточиться на обработке 
ваших данных, а не вычислять, где они находятся и как их сохранить. Чтобы 
активизировать средство кэширования схемы, необходимо для опции Enable Schema 
Cache установить значение True, а для параметра Schema Cache Dir указать путь 
к соответствующей папке. 
    • Количество пересылаемых пакетов. Установка параметра Batch Count 
определяет количество записей, которые пересылаются за одну операцию при 
выполнении пакетной пересылки. Увеличение значения этого параметра позволяет 
повысить скорость выполнения пакетных операций и средств перемещения данных. 
    Увеличение производительности путем управления явными транзакциями 
    Использование явных транзакций предоставляет не только большие возможности 
по контролю за их выполнением, но и позволяет увеличить производительность 
приложения. Для управления явными транзакциями установите опцию SQLPassThru 
Mode в программе BDE Administrator равной Shared. 

    Резюме 

    В этой главе речь шла о SQL-базах данных. Здесь были представлены язык SQL 
и два его подмножества — язык определения данных (DDL) и язык обработки данных 
(DML). Дав определение языка SQL, мы рассказали о преимуществах SQL-сервера. 
    Вы освоили утилиту Database Desktop для создания простых QBE-запросов и 
научились преобразовывать их в эквивалентный оператор SQL. 

    Глава 10. Работа с базами данных SQL 281 

    Затем в этой главе были перечислены ситуации, в которых необходимо 
использовать компонент ТТаЫе вместо TQuery, изложены связанные с SQL 
функциональные возможности, предоставляемые каждым из этих компонентов, а 
также рассмотрены способы повышения их эф4)ективности и скорости. 
    Кроме того, здесь описывались компоненты, которые используются при 
программировании для SQL-баз данных: 
    TDatabase, TStoredProc и TUpdateSQL. Компонент TDatabase используется для 
управления общим соединением с базой данных; класс TStoredProc содержит 
процедуры, хранящиеся на сервере, а компонент TUpdateSQL используется для 
модификации лежащих в его основе данных неизменяемого набора данных. 
    И, наконец, были рассмотрены некоторые дополнительные темы: управление 
явными транзакциями, использование параметров в операторах SQL, а также 
способы повышения общей производительности работы с SQL. 

    Компонент TStoredProc 

    Компонент TStoredProc используется для выполнения процедур, хранящихся на 
SQL-сервере. Эти процедуры могут возвращать набор данных для редактирования, 
изменять поле, модифицировать структуру таблицы, т.е. выполнять все то, что вы 
можете сделать на языке SQL. Хранение и выполнение процедур на сервере дает 
следующие преимущества. 
    • Централизация логики базы данных. С помощью создания хранимых процедур 
можно определить логику или бизнес-правила для наших данных в наиболее 
подходящем месте — в базе данных. Это означает, что все приложения, которым 
требуются функциональные возможности хранимых процедур, могут найти их в одном 
предопределенном месте. 
    • Зашита. Использование хранимых процедур предоставляет возможности для 
защиты доступа к уязвимым данным, используя функции защиты данных SQL-сервера. 
    • Скорость. Выполняя процедуры обработки данных на сервере, т.е. в том 
месте, где это быстрее всего можно сделать, вы сводите к минимуму сетевые и 
интерфейсные накладные расходы. 

    282                                     Часть III. Работа с базами данных 
