24. SQL-запросы

Синтаксис SQL-выражений в DataExpress (DX-SQL) почти такой же, как в Firebird-SQL.

Пример:

SELECT t.id, t.[номер] AS num, t.[дата] AS DATA, [клиенты].[название] AS client
FROM [продажа товара] t INNER JOIN [клиенты] ON t.[клиент]=[клиенты].id
ORDER BY t.[дата]

Отличительной особенностью DX-SQL является чередование названий форм и полей форм с названиями таблиц и полей базы данных. Названия форм и полей форм пишутся в квадратных скобках. В данном случае форма является аналогом таблицы.

Особенности DX-SQL

Перед тем как сделать запрос программа подменяет названия форм и полей в квадратных скобках на системные имена таблиц и полей. Если перед именем поля указан псевдоним или форма, то программа может точно определить к какой форме относится поле и если не находит его, то выдает сообщение об ошибке. Если псевдоним или форма не указана, то программа пытается его найти во всех формах, перечисленных в секции «FROM». При этом если поле не находится, то ошибка не появляется. Однако сервер выдаст сообщение об ошибке. Поэтому старайтесь указывать имена полей вместе с именем формы или псевдонимом. Обязательно пишите перед именем поля псевдоним или имя формы, если в имени поля есть точки.

Не используйте в качестве псевдонимов названия типа f1, f2, t1, t2, т. к. они могут совпасть с названиями полей и таблиц в базе данных. Используйте в псевдонимах только символы латинского алфавита, подчеркивание и цифры. При создании формы автоматические создается системное поле «id», которое является первичным ключом таблицы. При создании подчиненной формы дополнительно создается системное поле «pid», которое является внешним ключом и ссылается на id родительской формы.

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

Для работы с SQL используйте класс TdxSQLQuery и функцию SQLSelect:

function SQLSelect(const SQL: String): TdxSQLQuery

Класс TdxSQLQuery содержит почти тот же набор методов и свойств, что и форма.

Пример:

with SQLSelect('select id, [название] from [запчасти] order by [название]') do 
begin
  while not EOF do 
  begin
    // Какие-то действия
    … 
    MoveNext;
  end;
  Free;
end;

Кроме выборки данных класс умеет изменять данные в базе. Он, как и форма, имеет методы Append, Edit, Delete, Post, Cancel.

Главным отличием от формы является то, что метод Post сохраняет данные не в базе, а в наборе данных (подобно подчиненным формам).

Для отправки изменений в базу используется метод ApplyUpdates. Метод CancelUpdates может отменить все изменения, проделанные в наборе до вызова ApplyUpdates.

Необходимым условием для возможности изменений данных в базе является указание в SQL-запросе за словом «from» имени формы и наличие поля «id» формы. Класс автоматически генерирует инструкции Insert, Update и Delete. Набор полей формы, передаваемых в инструкции Insert и Update, берется из SQL-выражения.

Пример:

select pt.id, pt.[товар], pt.[цена], t.[название] from [приход товара] pt inner join [товары] t on pt.[товар]=t.id

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

Класс автоматически определяет генератор, который связан с формой. Свойство UseGenerator определяет как будет использован генератор:

  • ugNotUse - генератор не используется, id записи задается вручную;
  • ugAppend - id записи возвращается генератором при каждом добавлении записи;
  • ugApplyUpdates - перед сохранением изменений в базу значение генератора увеличивается на количество добавленных записей, а id новых записей заполняется значениями.

Выполнение произвольных SQL-инструкций

Процедура SQLExecute выполняет произвольный SQL-скрипт, передаваемый в параметре SQL.

procedure SQLExecute(const SQL: String)

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

Понять какая таблица связана с формой можно по ее идентификатору (свойство Id). К идентификатору добавляется префикс «t»:

't' + IntToStr(Form.Id)

Поле таблицы можно определить по идентификатору dx-компонента:

'f' + IntToStr(dxEdit.Id)

Редактор SQL-выражений

Редактор поможет вам составить выражение SQL. Откройте редактор:

Кнопка редактора на панели инструментов

Редактор SQL-выражений

Прямо в редакторе можно проверить выражение. Результат работы запроса отображается внизу. Нажмите вторую кнопку на панели инструментов, чтобы скопировать выражение в буфер обмена. Теперь вы можете его вставить в скрипт. Строки обрамляются в кавычки и соединяются символом+. Можно сделать наоборот, вставить скопированный текст SQL из скрипта в редактор. Для этого нажмите третью кнопку на панели инструментов. Лишние кавычки и символы + удаляются.

Сводные таблицы, таблицы и SQL-запросы

Сводные таблицы обычно используются в связке с запросом (TdxQueryGrid). Но если запрос не привязывать, то их можно использовать для отображения произвольных данных, например полученных SQL-запросом.

Также можно использовать таблицу (подчиненную форму) для отображения результата SQL-запроса. Эти данные уже можно использовать для печати шаблона.