
- •Методические указания к выполнению лабораторных работ по дисциплине
- •1. При проектировании используйте примеры программного кода непосредственно из исходных текстов программ, а не из методических описаний (*.Doc файла)
- •2. Имена отдельным модулям лучше давать по их функциональности, а не оставлять так как они даются по умолчанию (Unit1.Pas, Unit2.Pas и т.Д.)
- •3. При возникновении каких-либо ошибок в процессе выполнения работы проверьте по исходному примеру, все ли модули подключены в разделах interface и implementation, подразделе uses.
- •Теоретическое введение
- •Создание структуры таблиц бд
- •3.3 Синтез иконки прикладного приложения
- •3.4 Размеры экранных форм и их положение на экране
- •3.5 Разработка подчинённых форм
- •Создание формы
- •Размеры и положение
- •Работа приложения с бд
- •Доступ к таблицам бд. Компоненты доступа к данным. Приложение
- •AdoDataSet (Набор данных) или adoQuery (Запрос)
- •Сохранение пути к бд
- •Работа с данными
- •Обработка данных
- •Сортировка
- •Отчёты и обработки
- •Запросы, содержащие вычисления на выделенных записях таблицы (по столбцам)
- •В обработке события OnClick кнопки Button необходимо прописать следующее:
- •Разграничение прав доступа для различных пользователей
- •Организация многопользовательского режима
Работа с данными
Для работы с данными понадобятся следующие компоненты, расположенные на вкладке Data Controls:
DBNavigator
- необходим для перемещения по данным и работы с ними,
DBEdit - выводит текстовые и числовые поля записи для дальнейшего их редактирования,
DBLookupComboBox
- выводит поля, являющиеся связанными к данному набору данных, то есть содержащие в своем значении код связи, в виде выпадающего списка,
DBLookupListBox
- аналогичен компоненту DBLookupComboBox за тем исключением, что выводит данные не в выпадающий список, а в качестве строк поля.
Для удобства ввода
даты воспользуемся компонентом
DateTimePicker
с вкладки Win32.
Изменим форму справочника «Сотрудники» таким образом, как показано на рисунке 17.
Рисунок 17 – Справочник «Сотрудники» с компонентами работы с данными
Значения свойств компонентов приведены в таблице 2.
Таблица 2 - Значения свойств компонентов
Компонент |
Свойство |
Значение |
DBEdit0 |
CharCase |
ecUpperCase |
DataSource |
DM.SotrDataSource |
|
DataField |
S_ID |
|
Enabled |
False |
|
DBEdit1 |
CharCase |
ecUpperCase |
DataSource |
DM.SotrDataSource |
|
DataField |
S_Fam |
|
DBEdit2 |
CharCase |
ecUpperCase |
DataSource |
DM.SotrDataSource |
|
DataField |
S_Name |
|
DBEdit3 |
CharCase |
ecUpperCase |
DataSource |
DM.SotrDataSource |
|
DataField |
S_Otch |
|
DBEdit4 |
CharCase |
ecUpperCase |
DataSource |
DM.SotrDataSource |
|
DataField |
S_DateBirth |
|
Visible |
False |
|
DBLookupComboBox1 |
ListSource |
DM.DolgnostDataSource |
ListField |
D_NAME |
|
DataSource |
DM.SotrDataSource |
|
DataField |
S_D_ID |
|
KeyField |
D_ID |
|
DBLookupComboBox2 |
ListSource |
DM.HobbyDataSource |
ListField |
H_Name |
|
KeyField |
H_ID |
|
DBLookupListBox1 |
KeyField |
S_H_ID |
ListField |
H_Name |
|
ListSource |
DM.Hobby_SotrDataSource |
|
DBNavigator1 |
DataSource |
DM.SotrDataSource |
VisibleButtons |
[nbPrior,nbNext,nbInsert,nbDelete,nbEdit,nbPost,nbCancel,nbRefresh] |
Кнопки навигатора соответствуют действиям, представленным в таблице 3.
Таблица 3 – Кнопки и действия навигатора
nbFirst |
Устанавливает курсор на первую запись в наборе |
nbPrior |
Устанавливает курсор на предыдущую запись по отношению к выбранной |
nbNext |
Устанавливает курсор на следующую запись по отношению к выбранной |
nbLast |
Устанавливает курсор на последнюю запись |
nbInsert |
Для вставки новой записи |
nbDelete |
Удаляет выбранную запись из набора |
nbPost |
Запоминание изменений, сделанных в режиме добавления или изменения записи |
nbCancel |
Отменяет сделанные изменения в записи |
nbRefresh |
Обновляет данные |
Работать с кнопками навигатора можно точно так же, как с обычными стандартными кнопками. При этом можно использовать, например, события навигатора OnClick (возникает при щелчке «мышкой» по кнопке навигатора) и BeforeAction (возникает перед выполнением действия соответствующей кнопки навигатора).
Естественно, чтобы определить какая из кнопок навигатора была нажата надо в теле процедуры обработки вышеназванных событий использовать конструкцию:
If Button=nbDelete (или другая кнопка) then begin оператор1; оператор2; … end;
|
Пример процедуры BeforeAction для формы «Хобби»:
procedure TS_HobbyForm.DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn); begin ins:=false; // Если нажата кнопка «Вставить», тогда // передаём фокус в DBEdit1, если он доступен if Button=nbInsert then begin ins:=true; if DBEdit1.Enabled then DBEdit1.SetFocus; end; //Если нажата кнопка «Обновить», тогда проверяем признак редактирования if (Button=nbRefresh) then CheckEdit; end; |
Примечание: При запуске программа выдаст ошибку, так как процедура проверки признака редактирования CheckEdit ещё не прописана. Можно либо пока закомментировать строчку, содержащую обращение к процедуре, либо прописать процедуру (см. пункт 7 и программный пример), что лучше для проверки правильности функционирования.
При окончании редактирования даты в компоненте DateTimePicker её значение необходимо передать в DBEdit4, который невидим пользователю. Также при смене активной записи необходимо из поля DBEdit4 передавать данные в DateTimePicker.
То есть, для события OnCloseUp компонента DateTimePicker необходимо записать следующее:
procedure TS_sotrudnikiForm.DateTimePicker1CloseUp(Sender: TObject); begin // Нажимаем на DBNavigator1 кнопку редактирования DBNavigator1.BtnClick(nbEdit); // Передаём дату в DBEdit4 DBEdit4.EditText:=datetostr(DateTimePicker1.Date); end; |
Вывод графических полей
Для вывода поля записи, содержащей картинку, поместим на форму компонент Panel с вкладки Standard, а на него – компонент Image с вкладки Additional.
Не забудьте подключить в раздел uses (interface) модули:
- ExtCtrls, который включает обработку класса TImage (а также класс TTimer, который понадобится в дальнейшем),
- JPEG, включающий обработку класса ТJPEGImage,
- ExtDlgs, содержащий обработку классов TOpenPictureDialog, TSavePictureDialog.
Кроме того, необходимо вставить еще один компонент DBEdit (со свойствами DataSource – DM.SotrDataSource и DataField – Photo).
Необходимо также с вкладки Dialogs на форму переместить компонент OpenPictureDialogue. В свойстве Filter данного компонента необходимо указать следующее:
Рисунок18 – Настройка свойства Filter компонента OpenPictureDialog
Далее для работы с картинками нам необходимо будет прописать две функции: GetFileFormat (функция определяет расширение загружаемой картинки) и ExtractFileNameEx (функция определяет имя картинки с расширением или без него).
Пропишем эти функции в модуле DataModule. Для этого в разделе var перед разделом implementation необходимо объявить эти функции, при этом переменную DBPath необходимо сделать глобальной, чтобы она была доступна и для других модулей (т.е. тоже объявить в этом разделе), но тогда из фукнции TDM.ADOConnection1BeforeConnect объявление этой переменной необходимо убрать (см. пример), т.е.:
var DM: TDM; DBPath:widestring; // путь к БД function ExtractFileNameEx(FileName: string; ShowExtension: Boolean): string; function GetFileFormat(St: string): string; implementation |
После объявления данных функций, прописываем программный код их выполнения:
function GetFileFormat(St: string): string; //функция, определяющая расширение графического файла с точкой //(например, .jpg) //ВХОДНОЙ ПАРАМЕТР – имя картинки с расширением (например, Photo1.jpg) var z: integer; n: byte; begin // с помощью цикла определим количество знаков до точки // чтобы затем это количество знаков удалить из входной строки и получить расширение с точкой for z := length(St) -1 downto 0 do //начиная с предпоследнего знака (т.к. точка не может находиться в конце) //двигаемся по направлению к началу строки, т.е. z с каждым циклом уменьшается на 1 if (St[z] = '.') then //если очередной символ является точкой, то прекращаем цикл и запоминаем число z begin n := z; break; //прекращение цикла end; Delete(St, 1, n); //из исходной строки удалили найденное количество символов Result := St; end;
function ExtractFileNameEx(FileName: string; ShowExtension: Boolean): string; //ВХОДНЫЕ ПАРАМЕТРЫ //FileName - имя файла, которое надо обработать //ShowExtension - если TRUE, то функция возвратит короткое имя файла // (без полного пути доступа к нему), с расширением этого файла, иначе ,возвратит // короткое имя файла, без расширения этого файла. var I: Integer; S, S1: string; begin //Определяем длину полного имени файла I := Length(FileName); //Если длина FileName <> 0, то if I <> 0 then begin //С конца имени параметра FileName ищем символ "\" while (FileName[i] <> '\') and (i > 0) do i := i - 1; // Копируем в переменную S параметр FileName начиная после последнего // "\", таким образом переменная S содержит имя файла с расширением, но без // полного пути доступа к нему S := Copy(FileName, i + 1, Length(FileName) - i); i := Length(S); //Если полученная S = '' то фукция возвращает '' if i = 0 then begin Result := ''; Exit; end; //Иначе, получаем имя файла без расширения while (S[i] <> '.') and (i > 0) do i := i - 1; //... и сохраням это имя файла в переменную s1 S1 := Copy(S, 1, i - 1); //если s1='' то , возвращаем s1=s if s1 = '' then s1 := s; //Если было передано указание функции возвращать имя файла с его // расширением, то Result = s, //если без расширения, то Result = s1 if ShowExtension = TRUE then Result := s else Result := s1; end //Иначе функция возвращает '' else Result := ''; end; |
Так как имя графического файла содержит в себе код записи, к которой он относится, то необходимо обеспечить такую обработку кода записи, чтобы независимо от количества знаков в этом коде, все картинки имели одну и ту же точность в имени (например, 9 знаков), для унифицированной их обработки. Для этого рассмотрим функцию
FORMAT
Функция Format форматирует строку в соответствии с указанными инструкциями. Формат фукнции:
function Format (const Format: string; const Args: array of const) : string;
Первым параметром функции выступает форматирующая строка. Это — обычная текстовая строка, но в ней на нужных местах стоят специальные символы, которые определяют, какие и как туда будут подставлены параметры.
Второй параметр – список аргументов. Он и содержит "вставляемые" в форматирующую строку параметры. Обратите внимение, что этот открытый массив имеет тип array of const. и в нем может передаваться переменное число разнотипных параметров (индексация элементов в массиве начинается с нуля).
Общий формат форматирования каждой подстроки следующий:
%[Index:][-][Width][.Precision]Type
где квадратные скобки относятся к дополнительным параметрам (т.е. необязательным).
Здесь:
[Index:] - поле индекса аргумента, позволяющее динамически изменить последовательность извлечения аргументов из массива.
[-] – признак выравнивания по левому краю, позволяет выравнивать строку не по правому краю (как по умолчанию), а по левому.
[Width] – поле ширины, устанавливает минимально допустимое количество символов в выводимой строке, если она короче, чем задано, происходит добавление пробелов слева (по умолчанию) до нужного размера.
[.Precision] – поле точности, которое играет разную роль в зависимости от того, с каким типом преобразования применяется.
В простых условиях (без всех вышеперечисленных дополнительных полей) каждые данные, форматирующие подстроку начинаются с % и заканчиваются индикатором типа данных:
d = Десятичное (целое число)
e = Научный (число с плавающей точкой)
f = Установленный
g = Обобщенный (преобразуется к одному из вышеперечисленных видов – выбирается тот, который обеспечивает более короткую запись)
m = Деньги
n = Число (плавающее)
p = Указатель
s = Строка
u = Десятичное число без знака
x = Шестнадцатеричный
Пример 1 (использование типов преобразования):
Функция Результат
---------------------------------------------------------------------------------------
Format('Decimal= %d', [-123]); Decimal = -123
Format('Exponent=%e',[12345.678]); Exponent = 1.23456780000000E+004
Format('Fixed = %f', [12345.678]); Fixed = 12345.68
Format('General= %g', [12345.678]); General = 12345.678
Format('Number= %n', [12345.678]); Number = 12,345,68
Format('Money = %m', [12345.678]); Money = ?12,345.68
Format('Pointer= %p', [addr(text)]); Pointer = 0069FC90
Format('String = %s', ['Hello']); String = Hello
Format('Unsigned decimal = %u', [123]); Unsigned decimal = 123
Format('Hexadecimal = %x', [140]); Hexadecimal = 8C
Пример 2 (использование индекса, ширины и значения точности):
Функция Результат('<','>' - не выводятся)
---------------------------------------------------------------------------------------
// использование поля ширины (добавляются три пробела слева)
Format('Padded decimal = <%7d>', [1234]) Padded decimal = < 1234>
// использование выравнивания по левому краю
Format('Justified decimal = <%-7d>', [1234]); Justified decimal = <1234 >
// значение точности вынуждает 0 дополнений к желательному размеру
ShowMessage(Format('0 padded decimal=<%.6d>', [1234])); 0 padded decimal = <001234>
// комбинация ширины и точности
Format('Width + precision = <%8.6d>', [1234]); Width+precision=< 001234>
// индексное значение – при достижении 4ого параметра подставляется элемент массива под индексом 1 (индексация с нуля)
Format('Reposition after 3 strings = %s %s %s %1:s %s', ['Zero', 'One', 'Two', 'Three']);
Reposition after 3 strings = Zero One Two One Two
Необходимо создать в папке DB папку PIC, как в примере, или собственную папку, но тогда изменить программный код в некоторых местах. В этой папке будут храниться картинки, имена которых будут соответствовать коду записи, а точность имени будет содержать 9 знаков.
Далее в событии OnDblClick компонента Image следует написать следующий программный код:
procedure TS_sotrudnikiForm.Image1DblClick(Sender: TObject); var SourceFileName:string; FileFormat:string; DestFullFileName:widestring; { SourceFileName - полное имя файла (<путь>/<файл>.<расш>) изображения, выбранного пользователем FileFormat - расширение файла (.<расш>) изображения, выбранного пользователем DestFullFileName - сгенерированное полное имя файла (<путь>/<файл>.<расш>)} begin if (OpenPictureDialog1.Execute) then begin Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName); SourceFileName:=DataModule.ExtractFileNameEx(OpenPictureDialog1.FileName,True); FileFormat:= '.'+DataModule.GetFileFormat(SourceFileName); DBEdit.Text:=FileFormat; if (DBEdit0.Text<>'') then begin // нажимаем кнопку редактирования // изменяем формат DBNavigator1.BtnClick(nbEdit); // если загруженное изображение иного формата, то удаляем предыдущее изображение из папки, // иначе просто перезаписываем if DBEdit.Text<>FileFormat then DeleteFile(DataModule.DBPath+'PIC\'+Format('%.9d%s',[strtoint(DBEdit0.Text),DBEdit.Text])); DBEdit.Text:=FileFormat; DestFullFileName:=DataModule.DBPath+'PIC\'+Format('%.9d%s',[strtoint(DBEdit0.Text),FileFormat]); Image1.Picture.SaveToFile(DestFullFileName); end; end; end; |
Далее для того, чтобы показывать картинки при перемещении по записям, отслеживать их наличие, необходимо в событии OnChange компонента DBEdit0 (содержащего код записи) прописать следующее:
Примечание: не забудьте создать и описать переменную ins и функцию chekEdit, а также на модуль данных добавить необходимые компоненты доступа к данным. ( Смотри Пример программы.)
procedure TS_sotrudnikiForm.DBEdit0Change(Sender: TObject); var FileName:widestring; begin if (DBEdit0.Text<>'')and(not ins) then checkEdit; if (DBEdit0.Text<>'') then begin FileName:=DataModule.DBPath+'PIC\'+Format('%.9d%s',[strtoint(DBEdit0.Text),DBEdit.Text]); // если файл изображения НЕ СУЩЕСТВУЕТ, но ЗАДАННО расширение файла (новая запись), // тогда сохраняем файл из компонента Image1 (если Picture пустое, т.е. файл не загружен, то сохранения не произойдет) if (not FileExists(FileName))and(DBEdit.Text<>'') then Image1.Picture.SaveToFile(FileName); // если файл изображения СУЩЕСТВУЕТ и ЗАДАННО расширение файла // тогда загружаем его в компонент Image1 if (FileExists(FileName))and(DBEdit.Text<>'') then Image1.Picture.LoadFromFile(FileName) else Image1.Picture:=nil; DM.Hobby_SotrADOQuery.SQL.Text:= 'SELECT HOBBY_SOTR.S_H_ID, HOBBY_SOTR.S_ID, HOBBY_SOTR.H_ID, HOBBY.H_Name '+ 'FROM HOBBY INNER JOIN HOBBY_SOTR ON HOBBY.H_ID = HOBBY_SOTR.H_ID '+ 'WHERE (((HOBBY_SOTR.S_ID)='+DBEdit0.Text+'));'; DM.Hobby_SotrADOQuery.Open; end; end; |
Для работы с картинками осталось обработать действия DBNavigator, для этого в событии OnClick необходимо записать следующее:
procedure TS_sotrudnikiForm.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn); begin // при редактированние существующей записи // если кнопка принять и поля "код" и формат изобр. не пустые // тогда сохраняем (перезаписываем) файл if (Button=nbPost)and(DBEdit0.Text<>'')and(DBEdit.Text<>'') then Image1.Picture.SaveToFile(DataModule.DBPath+'PIC\'+Format('%.9d%s',[strtoint(DBEdit0.Text),DBEdit.Text])); end; |
Событие BeforeAction компонента DBNavigator определяет его действия, которые выполняются после нажатия на DBNavigator, но до выполнения основных действий (OnClick).
В этом событии для кнопки nbInsert вставим следующее:
if Button=nbInsert then begin Image1.Picture:=nil; end; |
Т.е. перед тем, как вставить новую запись, освобождаем поле графического файла.
При нажатии на кнопку nbDelete необходимо удалить графический файл, соответствующий удаляемой записи, из специально созданной для хранения этих файлов папки:
if (Button=nbDelete) then DeleteFile(DataModule.DBPath+'PIC\'+Format('%.9d%s',[strtoint(DBEdit0.Text),DBEdit.Text])); |
Создание кнопок для работы с данными
В свойстве SQL компонента Hobby_SotrADOQuery будет храниться запрос на выборку всех записей из таблицы Hobby_Sotr по соответствующему коду текущего сотрудника, т.е. результатом запроса будут все хобби выбранного сотрудника. Данный запрос будет формироваться динамически при событии смены текущего сотрудника.
Так как действия с основным набором данных происходят при помощи навигатора, то кнопки “Добавить”, “Изменить”, “Удалить” нужны для работы со связанными таблицами, выводящимися на той же форме, что и основной набор данных (в примере эти кнопки обрабатывают таблицу HOBBY_SOTH, в то время, как навигатор обслуживает таблицу SOTR).
Выбор таблицы, которую будут обслуживать данные кнопки, осуществляется в соответствие с техническим заданием и с логикой работы системы.
При нажатии на кнопки «Добавить», «Изменить», «Удалить» необходимо выполнять следующие действия:
«Добавить»:
Осуществить проверку на добавление пустой записи (если запись пустая то свойство KeyValue компонента DBLookupComboBox2 будет иметь значение null);
Осуществить проверку на наличие подобной записи у данного сотрудника (в этом случае удобно использовать функцию Locate(const <Поле>: string; const <значение>: Variant; <опции>: TLocateOptions): Boolean;)
DM.Hobby_SotrADOQuery.Locate('H_ID',DBLookupComboBox2.KeyValue,[loPartialKey])
Проверка осуществляется в том запросе, который соответствует обрабатываемой таблице, т.е. в примере – DM.Hobby_SotrADOQuery.Locate. В скобках 1ый параметр – имя поля, по которому идет поиск (не обязательно ключевое), 2ой параметр – значение, с которым сравнивается значения этого поля, т.е. типы данных 1ого и 2ого параметра должны совпадать, необходимо также указать опции или их отсутствие (в квадратных скобках).
В случае обнаружения подобной записи в базе данных, выводится сообщение:
MessageDlg('Данное хобби уже внесено в список!',mtWarning, [mbOk], 0)
Рассмотрим функцию
MessageDlg
Функция MessageDlg используется для отображения сообщений пользователю. Эти сообщения могут быть информационными, предупреждающими и др. Даётся полный свободный выбор кнопок, которые пользователь может нажать, чтобы подтвердить диалог.
function MessageDlg ( const Message : string; DialogType : TMsgDlgType; Buttons : TMsgDlgButtons; HelpContext : Longint ) : Integer;
Значение DialogType может иметь одно из следующих перечисленных значений:
mtWarning - отображает символ восклицания
mtError - отображает красный "Х" (ошибка)
mtInformation - отображает "i" в круге
mtConfirmation - отображает знак вопроса
mtCustom - отображает только сообщение
Значение Buttons может быть одним из следующих перечисленных значений:
mbYes - кнопка "Yes"
mbNo - кнопка "No"
mbOK - кнопка "OK"
mbCancel - кнопка "Cancel"
mbAbort - кнопка "Abort"
mbRetry - кнопка "Retry"
mbIgnore - кнопка "Ignore"
mbAll - кнопка "All"
mbNoToAll - кнопка "No to all"
mbYesToAll - кнопка "Yes to all"
mbHelp - кнопка "Help"
Вы задаёте эти значения в квадратных скобках разделённых запятой. Delphi обеспечивает множество предопределенных комбинаций кнопок:
mbYesNoCancel = [mbYes, mbNO, mbCancel]
mbYesAllNoAllCancel = [mbYes, mbYesToAll, mbNo, mbNoToAll, mbCancel]
mbOKCancel = [mbOK, mbCancel]
mbAbortRetryCancel = [mbAbort, mbRetry, mbCancel]
mbAbortIgnore = [mbAbort, mbIgnore]
Сформировать и выполнить запрос на добавление записи в таблицу;
Для добавления новой строки в таблицу используется оператор SQL – запроса INSERT. Существует два варианта использования данного оператора:
не определяются имена столбцов, т.к. вставляется новое значение в каждый столбец таблицы, но при этом количество значений должно точно соответствовать количеству столбцов таблицы. Синтаксис оператора:
INSERT INTO table_name VALUES (value1, value2, value3,...)
определяются имена конкретных столбцов и значения, которые необходимо вставить именно в эти столбцы:
INSERT INTO table_name (column1, column2, column3,...) VALUES (value1, value2, value3,...)
В примере реализован 2ой способ:
DM.Hobby_SotrADOQuery.SQL.Text:= 'INSERT INTO HOBBY_SOTR ( S_ID, H_ID ) VALUES ('+DBEdit0.Text+','+inttostr (DBLookupComboBox2.KeyValue ) + ');';
Так как все переменные (VALUES) являются внешними параметрами (т.е. не являются заранее известными), то оформляются вставками в SQL-запрос с помощью “+”. Причем, если вставляются только цифры (как в примере), то апострофов достаточно, если же необходимо вставить текст, то необходимо добавить двойные кавычки, например:
'INSERT INTO Brands_Of_Cars(Brand) VALUES ("'+Cars.Edit2.Text+'");';
Здесь в таблицу Brands_Of_Cars, содержащую марки машин, в столбец Brand вставляется нововведенная марка в поле Edit2 (является текстом).
После вставки новой записи в таблицу исполняется, но не открывается данный запрос:
DM.Hobby_SotrADOQuery.ExecSQL;
Восстановить прежний запрос;
«Изменить»:
Осуществить проверку на изменение на пустую запись;
Осуществить проверку на наличие подобной записи у данного сотрудника;
Эту проверку можно также осуществлять с использованием функции Locate.
Сформировать и выполнить запрос на обновление записи таблицы;
Для обновления существующей записи в таблице используется оператор SQL-запроса UPDATE. Синтаксис оператора:
UPDATE table_name SET column1=value, column2=value2,... WHERE some_column=some_value
В примере:
DM.Hobby_SotrADOQuery.SQL.Text:= 'UPDATE HOBBY_SOTR SET H_ID='+inttostr(DBLookupComboBox2.KeyValue) WHERE S_H_ID='+inttostr( DBLookupListBox1.KeyValue)+';';
Оператор WHERE определяет, какую запись необходимо обновить, если пропустить этот оператор, обновлены будут все записи.
Так же, как и с функцией INSERT, если необходимо обновить числовые значения – апострофов будет достаточно, если же текстовые – необходимо добавить еще и двойные кавычки.
Восстановить прежний запрос;
«Удалить»
Сформировать и выполнить запрос на удаление записи из таблицы;
Для удаления записи из таблицы используется оператор SQL-запроса DELETE. Синтаксис оператора:
DELETE FROM table_name WHERE some_column=some_value
Оператор WHERE определяет какая запись/записи будут удалены. Если пропустить этот оператор, будут удалены все записи.
В примере:
DM.Hobby_SotrADOQuery.SQL.Text:= 'DELETE * FROM HOBBY_SOTR WHERE S_H_ID='+inttostr(DBLookupListBox1.KeyValue)+';';
Восстановить прежний запрос;