Страница 1 из 1
Relation - копирование связаных файлов
Добавлено: 02 Июль 2015, 20:39
gopstop2007
Пришлось столкнуться с "вырезанием" связанных FileA и FileB (1:M) файлов данных по условию (Например: MyDate - Дата ) с последующим сохранением в результирующие файлы FileA_Rezultat и FileB_Rezultat, давно не сталкивался, боюсь ошибиться

Может есть более быстрый и результативный код?
Код: Выделить всё
Relate:FileA.SetQuickScan(1,Propagate:OneMany) !enable quickscan for 1:Many
Relate:FileB.SetQuickScan(1) !enable quickscan for primary
STREAM(FileA_Rezultat); STREAM(FileB_Rezultat)
LOGOUT(1,FileA,FileB)
SET(FileA)
LOOP
NEXT(FileA); IF ERRORCODE() THEN BREAK END
IF FileA.Date < MyDate THEN CYCLE END
FileA_Rezultat:RECORD = FileA:RECORD
Add(FileA_Rezultat); IF ERRORCODE() THEN STOP(ERROR()); ROLLBACK END
FileB.PrimariField = FileA.PrimariField
SET(FileB.PrimariKey,FileB.PrimariKey)
LOOP
NEXT(FileB); IF ERRORCODE() THEN BREAK END
IF FileB.PrimariField <> FileA.PrimariField THEN CYCLE END
FileB_Rezultat:RECORD = FileB:RECORD
Add(FileB_Rezultat); IF ERRORCODE() THEN STOP(ERROR()); ROLLBACK END
END
END
COMMIT
FLUSH(FileA_Rezultat); FLUSH(FileB_Rezultat)
Relate:FileB.SetQuickScan(0) !disable quickscan for primary
Relation - копирование связаных файлов
Добавлено: 02 Июль 2015, 22:34
Yufil
1. Сказал ABC - значит, ABC
Код: Выделить всё
Set(FileA)
LOOP While(~Access:FileA.Next() )
....
END
2. Нафиг Logout/Rollback/Commit, если FileA и FileB не пишутся. Эти операторы уместны для копий, а для первичных смысла не имеют.
3. Структура ключей PrimaryKey неизвестна, но
Код: Выделить всё
FileB.PrimariField = FileA.PrimariField
SET(FileB.PrimariKey,FileB.PrimariKey)
намекает, что отношение 1:1. Если 1:M то, как минимум, уместно
перед присваиванием
4.
Код: Выделить всё
IF FileB.PrimariField <> FileA.PrimariField THEN CYCLE END
Это приводит к просмотру ВСЕХ записей FileB с ключом больше, чем FileA.
Так что этот код надо крепко чинить. Нужно описание БД и постановка задачи.
Relation - копирование связаных файлов
Добавлено: 03 Июль 2015, 0:18
gopstop2007
Спасибо Юрий за замечания

Исправил, некоторые были допущены по невнимательности, спасибо что поправили. Может еще кто-то добавит свои 5 копеек
Код: Выделить всё
Relate:FileA.SetQuickScan(1,Propagate:OneMany) !enable quickscan for 1:Many
Relate:FileB.SetQuickScan(1) !enable quickscan for primary
STREAM(FileA_Rezultat); STREAM(FileB_Rezultat)
LOGOUT(1,FileA_Rezultat,FileB_Rezultat)
SET(FileA)
LOOP While(~Access:FileA.Next() )
IF FileA.Date < MyDate THEN CYCLE END
FileA_Rezultat:RECORD = FileA:RECORD
Add(FileA_Rezultat); IF ERRORCODE() THEN STOP(ERROR()); ROLLBACK END
FileB.PrimariField = FileA.PrimariField ! стать на первую запись для дальнейшего цикла FileB
SET(FileB.PrimariKey,FileB.PrimariKey)
LOOP While(~Access:FileB.Next() )
IF FileB.PrimariField <> FileA.PrimariField THEN BREAK END
FileB_Rezultat:RECORD = FileB:RECORD
Add(FileB_Rezultat); IF ERRORCODE() THEN STOP(ERROR()); ROLLBACK END
END
END
COMMIT
FLUSH(FileA_Rezultat); FLUSH(FileB_Rezultat)
Relate:FileB.SetQuickScan(0) !disable quickscan for primary
Relation - копирование связаных файлов
Добавлено: 03 Июль 2015, 6:16
Игорь Столяров
Мне не совсем понятен код, т.к. нет описания таблиц, но сам по себе код присвоения записей:
gopstop2007 писал(а):
FileA_Rezultat:RECORD = FileA:RECORD
FileB_Rezultat:RECORD = FileB:RECORD
является рискованным, даже если записи идентичны, малейшее нарушение
последовательностей полей приведет к краху. Лучше использовать поименованное
присваивание полей внутри записи: FileA_Rezultat:RECORD :=: FileA:RECORD
Relation - копирование связаных файлов
Добавлено: 03 Июль 2015, 10:02
Yufil
Вот этот кусок сомнителен. Если PrimaryKey - уникальный ключ по PrimaryField, то не нужен цикл,
FileB.PrimariField = FileA.PrimariField ! стать на первую запись для дальнейшего цикла FileB
IF ~Access:FileB.Fetch(FileB.PrimaryKey)
....
END
а если неуникальный, то нужно Clear на остальные поля ключа
Код: Выделить всё
Clear(FileB.Record)
FileB.PrimariField = FileA.PrimariField ! стать на первую запись для дальнейшего цикла FileB
SET(FileB.PrimariKey,FileB.PrimariKey)
LOOP While(~Access:FileB.Next() )
....
END
Relation - копирование связаных файлов
Добавлено: 03 Июль 2015, 12:51
gopstop2007
Игорь Столяров писал(а):... является рискованным, даже если записи идентичны, малейшее нарушение
последовательностей полей приведет к краху. Лучше использовать поименованное
присваивание полей внутри записи: FileA_Rezultat:RECORD :=: FileA:RECORD
Спасибо за замечание
Yufil писал(а):Вот этот кусок сомнителен. Если PrimaryKey - уникальный ключ по PrimaryField, то не нужен цикл,
FileB.PrimariField = FileA.PrimariField ! стать на первую запись для дальнейшего цикла FileB
IF ~Access:FileB.Fetch(FileB.PrimaryKey)
....
END
а если неуникальный, то нужно Clear на остальные поля ключа
Код: Выделить всё
Clear(FileB.Record)
FileB.PrimariField = FileA.PrimariField ! стать на первую запись для дальнейшего цикла FileB
SET(FileB.PrimariKey,FileB.PrimariKey)
LOOP While(~Access:FileB.Next() )
....
END
Ключ не уникальный, теперь понял
