|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
КОМАНДЫ РАБОТЫ С ЗАПИСЯМИADD (добавить новую запись)
ADD(файл,[длина])
Оператор ADD создает в файле новую запись и заполняет ее данными из буфера структуры RECORD. При выполнении ADD, обновляются все ключевые файлы (НЕ индексы!). Если происходит какая-либо ошибка, то запись не добавляется в файл. Конкретное действие ADD зависит от файлового драйвера. Если на диске не хватает места для размещения новой записи, то возвращается ошибка "Доступ запрещен". Возвращаемые ошибки: 05 Доступ запрещен 37 Файл еще не открыт 40 Такой ключ уже есть Пример: ADD(Customer) !Заносим данные о новом ! покупателе IF ERRORCODE() THEN STOP(ERROR()). !и проверяем на нали- ! чие ошибок. APPEND (добавить новую запись)
APPEND(файл[,длина])
Оператор APPEND вводит в файл данных новую запись из буфера, выделенного под структуру RECORD. Ключевые файлы НЕ обновляются. После добавления записи командой APPEND, надо перестроить ключи командой BUILD. Обычно APPEND используется для пакетного добавления нескольких записей в один прием (С.П.А - без обновления ключе, добавление записи, разумеется, происходит быстрее). Если на диске не хватает места для размещения новой записи, то возвращается ошибка "Доступ запрещен". Конкретное действие APPEND зависит от файлового драйвера. Возвращаемые ошибки: 05 Доступ запрещен 37 Файл еще не открыт Пример:
LOOP UNTIL EOF(InFile) !Обработка входного файла
NEXT(InFile) ! читаем все записи подряд
IF ERRORCODE() THEN STOP(ERROR()). ! Есть ошибки?
Cus:Record = Inf:Record !Копируем данные в буфер файла
! покупателей
APPEND(Customer) ! и ДОБАВЛЯЕМ новую запись в
! этот файл
IF ERRORCODE() THEN STOP(ERROR()). ! Есть ошибки?
. !Конец цикла обработки
BUILD(Customer) !А теперь перестроим ключи...
См. также: BUILD DELETE (удалить запись)
DELETE(файл)
Этот оператор удаляет последнюю запись, к которой происходило обращение операторами NEXT, PREVIOUS, GET, ADD или PUT. Также удаляются сведения об этой записи из ключевых файлов. DELETE не очищает буфер структуры RECORD, таким образом, данные удаленной записи остаются по-прежнему доступны до тех пор, пока содержимое буфера RECORD не изменится. Если не было обращения к какой-либо записи или запись блокирована другой рабочей станцией, DELETE возвращает ошибку "Запись недоступна" и удаления записи не происходит. Точное действие оператора DELETE зависит от файлового драйвера. Возвращаемые ошибки:
05 Доступ запрещен
33 Запись недоступна
Пример:
Customer FILE,DRIVER('Clarion'),PRE(Cus)
NameKey KEY(Cus:Name),OPT
NbrKey KEY(Cus:Number),OPT
Rec RECORD
Name STRING(20)
Number SHORT
. .
CODE
Cus:Number = 12345 !Инициализируем ключевое
! поле
GET(Customer,Cus:NbrKey) !Читаем соответствующую ему
! запись
IF ERRORCODE() THEN STOP(ERROR()).
DELETE(Customer) !Если это то, что нам надо,
! то удаляем эту запись.
См. также: ADD, GET, HOLD, NEXT, PREVIOUS, PUT GET (считать запись по прямому доступу)
файл,ключ
GET( файл,указатель_в_файле[,длина] )
ключ,указатель_в_ключе
Оператор GET находит заданную запись в файле данных и считывает ее в буфер структуры RECORD. Прямой доступ к записи осуществляется либо по относительному номеру записи в файле либо совпадению ключевого поля со значением заданного ключа.
Значения указателя_в_файле и указателя_в_ключе зависят от файлового драйвера. Это может быть: номер записи; номер байта в файле или какой-либо другой вид "опорной точки" в файле. Если значение указателя_в_файле или указателя_в_ключе выходят за разрешенные пределы или в файле нет подходящих по значениям записей, возникает ошибка "Запись не найдена". Возвращаемые ошибки: 35 Запись не найдена 37 Файл еще не открыт 43 Запись уже заблокирована Пример:
Customer FILE,DRIVER('Clarion'),PRE(Cus)
NameKey KEY(Cus:Name),OPT
NbrKey KEY(Cus:Number),OPT
Rec RECORD
Name STRING(20)
Number SHORT
. .
CODE
Cus:Name = 'Clarion' !Инициализируем ключевое поле
GET(Customer,Cus:NameKey) ! получаем соответствующую запись
IF ERRORCODE() THEN STOP(ERROR()).
GET(Customer,3) !Читаем третью физическую запись
! файла
IF ERRORCODE() THEN STOP(ERROR()).
GET(Cus:NameKey,3) !Получаем третью запись в порядке,
! задаваемом ключом NameKey
IF ERRORCODE() THEN STOP(ERROR()).
HOLD (монопольный доступ к записи)
HOLD(файл[,секунды])
Оператор HOLD включает блокирование записи для следующих за ним операторов GET, NEXT или PREVIOUS в многопользовательской среде. Когда GET, NEXT или PREVIOUS успешно захватывают запись, они выставляют флажок "held" (заблокирована). Обычно это не дает остальным пользователям изменять эту запись, но не мешает читать ее. Конкретное действие HOLD зависит от файлового драйвера.
В один момент времени только одна запись в каждом файле может быть заблокирована. Если происходит обращение к другой записи этого файла, то захваченная ранее запись автоматически освобождается. Так же как и для LOCK, существует проблема "смертельного объятия". Оно возникает когда две рабочих станции пытаются захватить один и тот же нвбор записей, но в разной последовательности и обе они используют оператор HOLD(файл). Одна станция уже захватила запись, которую пытается захватить другая и наоборот. Этой проблемы можно избежать, используя оператор HOLD(файл,секунды) и отслеживая возникновение ошибки "Запись уже заблокирована". Пример:
LOOP !Цикл во избежание "смертельного
! объятия"
HOLD(Master,1) !1 секунду пытаемся захватить запись глав-
! ного файла
GET(Master,1) !Читаем и блокируем запись
IF ERRORCODE() = 208 !Если кто-то уже захватил ее, то
BEEP(0,100); CYCLE ! подождем секунду и попробуем
! снова
.
HOLD(Detail,1) !1 секунду пытаемся захватить запись из
! файла подробностей
GET(Detail,1) !Читаем и блокируем запись
IF ERRORCODE() = 208 !Если кто-то уже захватил ее, то
RELEASE(Master) ! освободим захваченную ранее,
BEEP(0,100); CYCLE ! подождем секунду и попробуем
! снова
. . !Конец операторов IF и LOOP
См. также: RELEASE, GET, NEXT, PREVIOUS NEXT (прочитать следующую запись последовательности)
NEXT(файл)
NEXT читает из файла данных следующую, в ранее заданной последовательности, запись и заносит ее в буфер структуры RECORD. Оператор SET устанавливает последовательность, в которой будут считываться записи. Первый NEXT, выполнившийся сразу после SET, читает запись в позиции, установленной оператором SET. Последующие NEXT-ы читают следующие записи в этой последовательности. Последовательность не изменяется операторами GET, ADD, PUT или DELETE. Выполнение NEXT, перед которым не был выполнен SET, или попытка считать запись после конца файла, приводит к ошибке "Запись недоступна". Возвращаемые ошибки: 33 Запись недоступна 37 Файл еще не открыт 43 Запись уже заблокирована Пример:
SET(Cus:NameKey) !Начинаем с начала файла, последова-
! тельность задается ключом NameKey.
LOOP UNTIL EOF(Customer) !Читаем все, что можно, до конца фай-
! ла
NEXT(Customer) ! последовательно читаем записи
IF ERRORCODE() THEN STOP(ERROR()).
DO PostTrans ! вызываем процедуру обслуживания
! транзакций.
. !Конец цикла
См. также: SET, PREVIOUS, EOF, HOLD PREVIOUS (прочитать предыдущую запись последовательности)
PREVIOUS(файл)
PREVIOUS читает из файла данных предыдущую, в ранее заданной последовательности, запись и заносит ее в буфер структуры RECORD. Оператор SET устанавливает последовательность, в которой будут считываться записи. Первый PREVIOUS, выполнившийся сразу после SET, читает запись в позиции, установленной оператором SET. Последующие PREVIOUS-ы :) читают следующие записи этой последовательности В ОБРАТНОМ ПОРЯДКЕ. Последовательность не изменяется операторами GET, ADD, PUT или DELETE. Выполнение PREVIOUS, перед которым не был выполнен SET, или попытка считать запись перед началом файла, приводит к ошибке "Запись недоступна". Возвращаемые ошибки:
33 Запись недоступна
37 Файл еще не открыт
43 Запись уже заблокирована
Пример:
SET(Trn:DateKey) !Устанавливаем последовательность обра-
! ботки записей
LOOP UNTIL BOF(Trans) !Читаем все записи в обратном порядке
PREVIOUS(Trans) ! читаем записи последовательно
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut ! вызываем процедуру LIFO
. !Конец цикла
См. также: SET, NEXT, BOF, HOLD PUT (записать запись обратно в файл)
PUT(файл[,указатель_в_файле][,длина])
Оператор PUT записывает содержимое буфера RECORD в последнюю запись, к которой производилось обращение.
Если к записи не было обращения операторами NEXT, PREVIOUS, GET и ADD или она была удалена, то возвращается ошибка "Запись недоступна". PUT также может вернуть ошибку "Такой ключ уже есть". При возникновении какой-либо ошибки файл не изменяется. Возвращаемые ошибки:
05 Доступ запрещен
33 Запись недоступна
40 Такой ключ уже есть
Пример:
SET(Trn:DateKey) !End/Beginning of file in keyed sequence
LOOP UNTIL BOF(Trans) !Читаем все записи в обратном порядке
PREVIOUS(Trans) ! одну за другой
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut !Вызываем процедуру LIFO
PUT(Trans) !Записываем транзакцию обратно в файл
IF ERRORCODE() THEN STOP(ERROR()).
. !Конец цикла
См. также: NEXT, PREVIOUS, GET, ADD RELEASE (освободить заблокированную запись)
RELEASE(файл)
Оператор RELEASE освобождает захваченную ранее запись. Он не может освободить запись, захваченную другим пользователем. Если запись не захвачена или захвачена другим пользователем, то этот оператор игнорируется. Пример:
LOOP !Цикл во избежание "смертельного объятия"
HOLD(Master,1) !1 секунду пытаемся захватить главный файл
GET(Master,1) !получаем и блокируем запись
IF ERRORCODE() = 208 !если кто-то успел раньше нас, то
BEEP(0,100) ! секунду подождем
CYCLE ! и попробуем еще раз
.
HOLD(Detail,1) !1 секунду пытаемся захватить файл
! подробностей
GET(Detail,1) !получаем и блокируем запись
IF ERRORCODEO = 208 !если кто-то успел раньше нас, то
RELEASE(Master) ! осободим запись, захваченную ранее
BEEP(0,100) ! секунду подождем
CYCLE ! и попробуем еще раз
. . !Конец операторов IF и LOOP
RESET (сброс указателя текущей записи)
RESET(последовательность,строка)
RESET устанавливает указатель записи на запись, задаваемую строкой, возвращаемой функцией POSITION. После того, как RESET установил указатель, NEXT или PREVIOUS могут считать эту запись. Значение, содержащееся в СТРОКЕ, и его длина зависят от файлового драйвера. RESET, обычно, используется вместе с POSITION для временного изменения порядка обработки записей. Пример:
RecordQue QUEUE,PRE(Dsp)
QueFields LIKE(Trn:Record),PRE(Dsp)
.
SavPosition STRING(260)
CODE
SET(Trn:DateKey) !Top of file in keyed sequence
LOOP !Последовательно читаем
NEXT(Trans) ! записи, одну за другой
IF ERRORCODE() THEN STOP(ERROR()).
RecordQue = Trn:Record !Помещаем запись в очередь
ADD(RecordQue) !
IF ERRORCODE() THEN STOP(ERROR()).
IF RECORDS(RecordQue) >= 20 OR EOF(Trans)
!В очереди 20 записей?
SavPosition = POSITION(Trn:DateKey) !сохраним указатель
!на текущую запись
DO DisplayQue !Выведем очередь на экран
FREE(RecordQue) ! и очистим ее
IF EOF(Trans) THEN BREAK.
!Если обработаны все записи, то выходим
RESET(Trn:DateKey,SavPosition) !Сбрасываем указатель
. . !Конец цикла
См. также: POSITION, NEXT, PREVIOUS SET (инициировать последовательную обработку файла)
файл
SET( файл,ключ )
файл,указатель_в_файле
ключ
ключ,ключ
ключ,указатель_в_ключе
ключ,ключ,указатель_в_файле
SET инициирует последовательную обработку файла. SET НЕ считывает запись, а только устанавливает порядок обработки и начальную точкц для последующих операторов NEX или PREVIOUS. Первый параметр определяет порядок обработки записей. Второй и третий - задают первую обрабатываемую запись (начальную точку обработки). Если они опущены, то обработка начнется с начала (или конца) файла.
Если второй параметр - ключ, то обработка начнется с первой записи, содержащей значения, наиболее близкие к значениям компонент ключа или индекса. Если найдено ТОЧНОЕ совпадение, то и NEXT и PREVIOUS считают найденную запись. Если нет точного совпадения, то NEXT прочитает запись с ближайшим БОЛЬШИМ значением, а PREVIOUS - с ближайшим меньшим. Значения указателя_в_файле и указателя_в_ключе зависят от файлового драйвера. Это может быть номер записи, относительный номер байта в файле или какой либо иной вид "опорной точки" в файле. Эти параметры используются для начала обработки с конкретной записи в файле. Пример:
SET(Customer) !Обработка в физическом порядке
Cus:Name = 'Smith'
SET(Customer,Cus:NameKey)
!Обработка в физическом порядке, начиная с записи, в
! которой поле Name = 'Smith'
SavePtr = POINTER(Customer)
SET(Customer,SavePtr)
!Обработка в физическом порядке, начиная с записи,
! физический номер которой хранится в SavePtr
SET(Cus:NameKey)
!Обработка в порядке, задаваемом ключом NameKey
SavePtr = POINTER(Cus:NameKey)
SET(Cus:NameKey,SavePtr)
!Обработка в порядке, задаваемом ключом NameKey, с за-
! писи, относительный номер которой в ключе содержит
! SavePtr
Cus:Name = 'Smith'
SET(Cus:NameKey,Cus:NameKey)
!Обработка в порядке, задаваемом ключом NameKey, начи-
! ная с первой записи, в которой поле = 'Smith'
Cus:Name = 'Smith'
SavePtr = POINTER(Customer)
SET(Cus:NameKey,Cus:NameKey,SavePtr)
!Обработка в порядке, задаваемом ключом NameKey,
! Name = 'Smith' и номер записи = SavePtr
См. также: NEXT, PREVIOUS, KEY, RECORDS, POINTER SKIP (пропустить записи в последовательности)
SKIP(файл,count)
Оператор SKIP используется для пропуска записей во время последовательной обработки файла. Он пропускает записи в порядке, задаваемом оператором SET, перемещая указатель записи в файле на COUNT записей вперед или назад. SKIP более эффективен, чем NEXT или PREVIOUS при пропуске нескольких записей, поскольку он НЕ считывает записи в буфер, отведенный под структуру RECORD. Если SKIP пытается выйти за конец или начало файла, то функции EOF() и BOF() возвращают истину. Если ранее не был выполнен SET, то SKIP игнорируется. Пример:
SET(Itm:InvoiceKey) !Начинаем от начала файла товаров
LOOP UNTIL EOF(Items) !Обрабатываем все записи
NEXT(Items) !Читаем запись
IF ERRORCODE() THEN STOP(ERROR()).
IF Itm:InvoiceNo <> SavinvNo !Если это первый товар в зака-
! зе, то
Hea:InvoiceNo = Itm:InvoiceNo !инициализируем ключевое
! поле и
GET(Header,Hea:InvoiceKey)
!получаем соответствующий ему за-
! головок столбца
IF ERRORCODE() THEN STOP(ERROR()).
IF Hea:InvoiceStatus = 'Cancel' !Если заказ отменен,
SKIP(Items,Hea:ltemCount-1) ! то пропускаем осталь-
! ные товары
CYCLE ! и обрабатываем следую-
! щий заказ
. . ! конец операторов IF
DO ItemProcess ! обрабатываем товар
SavInvNo = Itm:lnvoiceNo ! сохраняем номер счета
. !Конец цикла
ФУНКЦИИ РАБОТЫ С ФАЙЛОМBOF (начало файла)
BOF(файл)
Функция BOF возвращает НЕнулевое значение (истину), если операторами PREVIOUS или SKIP(-count) была прочитана или пропущена самая первая запись последовательности. В противном случае возвращается ноль (ложь). Функция BOF наиболее часто используется для проверки условия в цикле LOOP UNTIL. Поскольку условие выполнения этого цикла вычисляется в НАЧАЛЕ цикла, то BOF вернет ИСТИНУ после прочтения первой записи последовательности. Тип возвращаемого результата: LONG Пример:
SET(Trn:DateKey) !Пляшем от конца файла по ключу
LOOP UNTIL BOF(Trans) !Обрабатываем файл с конца
PREVIOUS(Trans) ! последовательно читая записи
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut ! вызываем процедуру LIFO
. !Конец цикла
См. также: PREVIOUS, SKIP, LOOP BYTES (размер файла в байтах)
BYTES(файл)
Функция BYTES возвращает размер в байтах либо файла, либо последней записи, к которой было обращение. Если выполнить BYTES сразу после открытия файла, то она вернет размер этого файла. После того, как к файлу обратились операторами GET, NEXT, ADD или PUT, BYTES верней размер в байтах записи, прочитанной в структуру RECORD. Функцию BYTES можно использовать для того, чтобы узнать, сколько было прочитано байт при работе с записями переменной длины. Пример:
OPEN(DosFile) !Открыть файл
IF (BYTES(DosFile) % 80) > 0 !Check for short record
SavPtr = INT(BYTES(DosFile)%80)+1
! compute short record pointer
ELSE
SavPtr = BYTES(DosFile)/80 ! compute last record pointer
.
GET(DosFile,SavPtr) !Get the last record
LastRec = BYTES(DosFile) !Save size of the short record
DUPLICATE (проверить на дублирование ключевых полей)
DUBLICATE(ключ)
файл
Функция DUPLICATE возвращает НЕнулевое значение (истину), если при внесении записи в файл возникла ошибка "Такой ключ уже есть" ("CREATES DUPLICATE KEY"). Если задан параметр КЛЮЧ, то проверяется заданный ключевой файл. С параметром ФАЙЛ проверяются все ключи, описанные без атрибута DUP. Функция DUPLICATE подразумевает, что содержимое структуры RECORD аналогично содержимому записи, на которую указывает указатель текущей записи. Таким образом, при использовании DUPLICATE ДО добавления записи, указатель текущей записи должен быть очищен командой GET(файл,0). Тип возвращаемого результата: LONG Пример:
IF Action = 'ADD' THEN GET(Vendor,0).
!При добавлении очищаем указатель
IF DUPLICATE(Vendor) !Если такой продавец уже есть, то
SCR:MESSAGE = 'Уже есть продавец с таки номером'
! выводим сообщение
SELECT(?) ! и снова ждем ввода в тоже самое
! поле
. !Конец оператора if
См. также: GET EOF (конец файла)
EOF(файл)
Функция EOF возвращает ИСТИНУ (НЕ ноль) если была прочитана (оператором NEXT) или пропущена (оператором SKIP) последняя запись последовательности. В противном случае возвращается ЛОЖЬ (нулевое значение). Функция EOF обычно используется для проверки условия в циклах LOOP UNTIL. Поскольку условие в таком цикле вычисляется в начале цикла, то EOF вернет ИСТИНУ после того, как будет прочитана последняя запись. Тип возвращаемого результата: LONG Пример:
SET(Trn:DateKey) !Пляшем от начала файла по ключу
LOOP UNTIL EOF(Trans) !Обрабатываем файл с начала,
PREVIOUS(Trans) ! последовательно читая записи
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut ! вызываем процедуру LIFO
. !Конец цикла
POINTER (относительный номер записи)
POINTER(файл)
ключ
POINTER возвращает относительный номер записи в файле или в последовательности либо относительное положение указателя на запись в ключе или индексе (в последовательности "по ключу"). Значение, возвращаемое функцией, зависит от файлового драйвера. Это может быть номер записи, относительный номер байта в файле или какой-либо другой вид "опорной точки в файле". Тип возвращаемого результата: LONG Пример:
SavePtr# = POINTER(Customer) !Сохраняем указатель на запись
См. также: SET POSITION (номер записи в последовательности)
POSITION(последовательность)
POSITION возвращает строку, которая идентифицирует уникальный номер записи в последовательности. POSITION возвращает положение в файле последней записи, к которой происходило обращение (то есть содержимое записи находится в буфере структуры RECORD). Значение и длина возвращаемой строки зависят от файлового драйвера. POSITION используется совместно с RESET для временного изменения порядка обработки записей, и, затем, его восстановления. Тип возвращаемого результата: STRING Пример:
RecordQue QUEUE,PRE(Dsp)
QueFields LIKE(Trn:Record),PRE(Dsp)
.
SavPosition STRING(260)
CODE !От начала файла идем по ключу
SET(Trn:DateKey) !Последовательно читаем
LOOP ! все записи
NEXT(Trans)
IF ERRORCODE() THEN STOP(ERROR()).
RecordOue = Trn:Record !Добавляем запись в
ADD(RecordQue) ! очередь
IF ERRORCODE() THEN STOP(ERROR()).
IF RECORDS(RecordOue) >= 20 OR EOF(Trans)
!если в очереди 20 записей, то
SavPosition = POSITION(Trn:DateKey) !сохраняем номер теку-
! щей записи,
DO DisplayQue !показываем очередь и
FREE(RecordQue) ! очищаем ее
IF EOF(Trans) THEN BREAK.
!Если все записи обработаны, то
! заканчиваем работу
RESET(Trn:DateKey,SavPosition) !Восстанавливаем указатель
. . !Конец цикла
См. также: RESET RECORDS (число записей)
RECORDS(файл)
ключ
Эта функция количество записей в файле или ключе. Поскольку атрибут OPT для ключа или индекса не дает заносить в них данные о записях, у которых ключевые поля пусты, то RECORDS может вернуть для ключа или индекса меньшее значение чем для файла, к которому они принадлежат. Тип возвращаемого результата: LONG Пример:
SaveCount = RECORDS(Master) !Сохраняем количество записей
SaveNameCount = RECORDS(Nam:NameKey)
!Число карточек, в которых заполнено
! поле NAME
SEND (отправить сообщение файловому драйверу)
SEND(файл,сообщение)
Функция SEND позволяет программе передать файловому драйверу, во время выполнения, специфичные параметры. Примеры таких специфичных параметров приведены в документации на драйвер. Тип возвращаемого результата: STRING Пример:
FileCheck = SEND(ClarionFile,'RECOVER=120')
!Запустить восстановление для файла
! в стандарте Кларион
ОБРАБОТКА ТРАНЗАКЦИЙCOMMIT (завершить успешно проведенную транзакцию)
COMMIT
Оператор COMMIT завершает активную транзакцию. Выполнение оператора COMMIT подразумевает, что транзакция успешно завершена и не возникнет необходимость выполнения ROLLBACK. После выполнения COMMIT, выполнение ROLLBACK становится НЕВОЗМОЖНЫМ. COMMIT информирует участвующий в транзакции файловый драйвер о том, что временные файлы, необходимые для приведения базы в исходное состояние (как было до транзакции), можно удалять. После этого, файловый драйвер производит действия, необходимые в его файловой системе для завершения транзакции. Пример:
LOGOUT(.1,OrderHeader,OrderDetail) !Начинаем транзакцию
DO ErrHandler ! нет ли ошибок?
ADD(OrderHeader) !Добавим запись о родителе
DO ErrHandler ! нет ли ошибок?
LOOP X# = 1 TO RECORDS(DetailQue)
!Обработка сохраненных подробностей
GET(DetailQue,X#) !Читаем одну из очереди
DO ErrHandler ! нет ли ошибок?
Det:Record = DetailOue !Помещаем в буфер записи
ADD(OrderDetail) ! и добавляем ее в файл
DO ErrHandler ! нет ли ошибок?
.
COMMIT !Завершаем успешную транзакцию
ErrHandler ROUTINE !Обработчик ошибок
IF NOT ERRORCODE() THEN EXIT. !Ошибок нет? Вернемся.
ROLLBACK !Отмена прерванной транзакции
BEEP !Предупреждаем пользователя
SHOW(25,1,'Ошибка транзакции - ' & ERROR())
ASK ! и ждем нажатия клавиши
RETURN ! затем возвращаемся
LOGOUT (начать транзакцию)
LOGOUT(таймаут,файл[,файл,...,файл])
Оператор LOGOUT начинает обработку транзакции для заданного файла или набора файлов. Все задействованные файлы должны работать с одним и тем же файловым драйвером. LOGOUT сообщает драйверу о начале транзакции. Драйвер, в свою очередь, выполняет действия, необходимые в его файловой системе для начала обработки транзакции в заданном наборе файлов. Если файловая система требует, чтобы файлы были заблокированы перед началом транзакции, то LOGOUT автоматически блокирует их (для этого и нужен ТАЙМАУТ). Только одна транзакция, инициированная через LOGOUT, может выполняться одновременно. Второй LOGOUT (без предварительного COMMIT или ROLLBACK) останавливает программу с сообщением об ошибке и вываливается в DOS. Возвращаемые ошибки:
32 Файл уже заблокирован
Пример:
LOGOUT(,1,OrderHeader,OrderDetail) !Начинаем транзакцию
DO ErrHandler ! нет ли ошибок?
ADD(OrderHeader) !Добавим запись о родителе
DO ErrHandler ! нет ли ошибок?
LOOP X# = 1 TO RECORDS(DetailQue)
!Обработка сохраненных подробностей
GET(DetailQue,X#) !Читаем одну из очереди
DO ErrHandler ! нет ли ошибок?
Det:Record = DetailQue !Помещаем в буфер записи
ADD(OrderDetail) ! и добавляем ее в файл
DO ErrHandler ! нет ли ошибок?
.
COMMIT !Завершаем успешную транзакцию
ErrHandler ROUTINE !Обработчик ошибок
IF NOT ERRORCODE() THEN EXIT. !Ошибок нет? Вернемся.
ROLLBACK !Отмена прерванной транзакции
BEEP !Предупреждаем пользователя
SHOW(25,1,'Ошибка транзакции - ' & ERROR())
ASK ! и ждем нажатия клавиши
RETURN ! затем возвращаемся
ROLLBACK (завершить ошибочную транзакцию)
ROLLBACK
Оператор ROLLBACK завершает текущую транзакцию как и COMMIT. Выполнение оператора ROLLBACK подразумевает, что транзакция прошла НЕВЕРНО и база данных нуждается в восстановлении в то состояние, в котором она была до транзакции. ROLLBACK сообщает файловому драйверу, участвующему в транзакции, о том, что временные файлы, необходимые для возвращения базы в первоначальное состояние, должны быть использованы для восстановления базы. Драйвер, в свою очередь, выполняет действия, которые необходимы в его файловой системе для отката транзакции. Пример: LOGOUT(,1,OrderHeader,OrderDetail) !Начинаем транзакцию
DO ErrHandler ! нет ли ошибок?
ADD(OrderHeader) !Добавим запись о родителе
DO ErrHandler ! нет ли ошибок?
LOOP X# = 1 TO RECORDS(DetailQue)
!Обработка сохраненных подробностей
GET(DetailQue,X#) !Читаем одну из очереди
DO ErrHandler ! нет ли ошибок?
Det:Record = DetailQue !Помещаем в буфер записи
ADD(OrderDetail) ! и добавляем ее в файл
DO ErrHandler ! нет ли ошибок?
.
COMMIT !Завершаем успешную транзакцию
ErrHandler ROUTINE !Обработчик ошибок
IF NOT ERRORCODE() THEN EXIT. !Ошибок нет? Вернемся.
ROLLBACK !Отмена прерванной транзакции
BEEP !Предупреждаем пользователя
SHOW(25,1,'Ошибка транзакции - ' & ERROR())
ASK ! и ждем нажатия клавиши
RETURN ! затем возвращаемся
Назад | Содержание | Вперед |
|
CITForum © 1997–2025