СОЗДАНИЕ, УДАЛЕНИЕ И РЕДАКТИРОВАНИЕ ЗАПИСЕЙ


СОЗДАНИЕ ЗАПИСИ


Для добавления новой записи в таблицу используются операторы CREATE и INSERT.


ОПЕРАТОР CREATE


rec-work01.jpg

Оператор CREATE создает новую запись в таблице, при этом поля таблицы которым определены начальные значения заполняются ими. Так же эта запись помещается в буфер записи.

CREATE record [NO-ERROR]

После того как новая запись создана возможно заполнение ее полей, например с помощью оператора присваивания ASSIGN, либо с помощью оператора UPDATE.

Пример ASSIGN:

CREATE customers.
ASSIGN
   customers.name = "Иванов Иван Иванович"
   customers.birthday = 87/09/15
   customers.inn = 123456789012
.

Пример UPDATE:

CREATE customers.
UPDATE customer.name customers.birthday customers.inn.

Более подробно об операторе UPDATE будет рассказано в разделе редактирование записи.


ОПЕРАТОР INSERT


rec-work02.jpg

Оператор INSERT создает новую запись подобно оператору CREATE, но в отличии от него помещает ее еще и в экранный буфер, где она становиться доступной для ввода данных пользователю.

INSERT record [EXCEPT field ...]
  [frame-phrase]
  [NO-ERROR]

  • record - буфер записи таблицы, в которую осуществляется добавление записи;
  • EXCEPT field  - список исключаемых полей, указываемых через разделитель пробел;
  • frame-phrase - параметры FRAME экранной формы ввода данных.

Для примера осуществим ввод лицевого счета в АБС Бисквит (таблица acct).

INSERT acct WITH 2 COLUMNS NO-ERROR.

insert.jpg

По умолчанию, оператор INSERT использует DEFAULT-FRAME, но это не всегда удобно. Гораздо удобнее и более нагляднее создание свой формы заполнения записи.

DEF FRAME frame1 customers.fio       LABEL "ФИО" 
                 customers.birthday LABEL "День рождения"
WITH TITLE "Добавление".    
INSERT customers.fio customers.birthday WITH FRAME frame1.

Таким образом, операция

INSERT customers.

аналогична комбинации операторов:

CREATE customers.
UPDATE c
ustomers.


УДАЛЕНИЕ ЗАПИСИ


Для удаления записи ее сначала нужно поместить в буфер записи, например с помощью оператора FIND.

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

DELETE record
  [VALIDATE (condition, msg-expression)]
  [NO-ERROR ]

  • record - буфер записи таблицы, из которой осуществляется удаление записи;
  • condition - логическое выражение, определяющее выполнять удаление или нет, тип LOGICAL;
  • msg-expression - текст сообщения, тип CHAR.
FIND FIRST customers WHERE customers.name     EQ "Иванов Иван Иванович"
                       AND customers.birthday EQ 87/09/15
                       AND customers.inn      EQ 123456789012
                     NO-LOCK NO-ERROR.
IF AVAIL customers THEN DELETE customers.

Для ограничения возможных удаляемых записей, DELETE может использоваться с опцией VALIDATE.

Например, есть таблица acct (счета) и есть таблица op (проводки по счетам). Нужно сделать так, чтоб невозможно было удалить счет из таблицы счетов если по нему были проводки. 

Если condition имеет значение TRUE, то запись будет удалена. В противном случае будет выведено сообщение msg-expression и запись не будет удалена из таблицы.

DEF VAR iLog AS LOGICAL NO-UNDO.
FIND FIRST acct WHERE acct.acct EQ "40817810300000000001"
                NO-LOCK NO-ERROR.
IF AVAIL acct THEN
DO:
  FIND FIRST op OF acct NO-LOCK NO-ERROR.
   IF AVAIL op THEN iLog = FALSE.
               ELSE iLog = TRUE.
   DELETE acct VALIDATE(iLog,"Есть операции по счету, удаление невозможно!").
END.


РЕДАКТИРОВАНИЕ
ЗАПИСИ


Первоначально редактируемая запись должна быть помещена в буфер записи, например с помощью FOR, FIND, CREATE и т.д.

rec-work03.jpg

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

UPDATE record
   [EXCEPT field ...]
   [frame-phrase]
   [NO-ERROR]

  • record - буфер записи, либо список полей с разделителем пробел;
  • EXCEPT field - список исключаемых полей с разделителем пробел;
  • frame-phrase - параметры FRAME экранной формы.

UPDATE по умолчанию использует DEFAULT-FRAME, если FRAME в котором будет производится редактирование записи не указан явно.

DEF FRAME frame1 customers.fio      LABEL "ФИО" 
                 customers.birthday LABEL "День рождения"
WITH TITLE "Редактирование". 

FIND FIRST customers WHERE customers.birthday > 01/01/2001 NO-ERROR.
IF AVAIL customers THEN 
UPDATE customers.fio customers.birthday WITH FRAME frame1.

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

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

Создадим временную таблицу студентов содержащую два поля: name (имя студента) и kurs (курс на котором учиться студент). Для примера, введем в таблицу две записи студентов 1-го курса: Иванова и Петрова. Допустим, что прошел учебный год и нам необходимо перевести всех студентов на курс выше.

DEF TEMP-TABLE tt-student NO-UNDO
   FIELD name  AS CHAR
   FIELD kurs  AS INTEGER
.

CREATE tt-student.
ASSIGN
  tt-student.name = "Иванов"
  tt-student.kurs = 1
.

CREATE tt-student.
ASSIGN
  tt-student.name = "Петров"
  tt-student.kurs = 1
.

FOR EACH tt-student:
  tt-student.kurs = tt-student.kurs + 1.
  DISPL tt-student.
END.

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

Создадим в таблице PRIMARY индекс состоящего из поля kurs и повторим операцию.

DEF TEMP-TABLE tt-student NO-UNDO
   FIELD name  AS CHAR
   FIELD kurs  AS INTEGER
   INDEX idx-kurs IS PRIMARY kurs  
.

CREATE tt-student.
ASSIGN
  tt-student.name = "Иванов"
  tt-student.kurs = 1
.

CREATE tt-student.
ASSIGN
  tt-student.name = "Петров"
  tt-student.kurs = 1
.

FOR EACH tt-student:
  tt-student.kurs = tt-student.kurs + 1.
  DISPL tt-student.
END.

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

Вы здесь: Главная Основы ABL СОЗДАНИЕ, УДАЛЕНИЕ И РЕДАКТИРОВАНИЕ ЗАПИСЕЙ