On-line: Pasha, Haz, гостей 1. Всего: 3 [подробнее..]
АвторСообщение





Пост N: 518
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 28.03.17 23:47. Заголовок: Как модифицировать таблицу с AUTOINC полем ?


Добрый день.

Много лет использовал такой алгоритм модификации таблиц:
 
FUNC TableUpdate(cName,aNewStruct)

...
USE (cName) NEW
aOldStruct := DBSTRUCT()
CLOSE (cName)
//
IF !ArrayEqual(aOldStruct,aNewStruct) // сравнение двух массивов "вглубь", с рекурсией.
DBCREATE("temp",aNewStruct)
USE temp
APPEND FROM (cName)
CLOSE temp
FRENAME(cName+".dbf",cName+".old")
FRENAME("temp.dbf",cName+".dbf")
ENDIF
...
INDEX ON ... TO ...
...
И буквально сегодня столкнулся с собственным разгильдяйством. Модифицировал справочник, в котором одно из полей - "чистый" autoincrement: {"id","+",4,0}.
В исходной таблице были удалены пара записей, соответственно после APPEND соответствующие ID "поплыли".
Ситуацию конечно исправил, заменив поле на "I:+" с автоматическим поиском соответсвтий по другим полям и добавлением пары пустых записей.

Разумеется, теперь поставил в TableUpdate() заглушку, отменяющую преобразования, если в исходной таблице будет найдено поле с типом "+". Если, вдруг забуду...

Но вот читаю усиленно доки по Harbour, вспоминаю "классические" команды Clipper и не очень понимаю, как вообще, в принципе, поменять структуру таблиц, в которых есть "настоящие" AUTOINC поля, чтобы не наступить на те-же самые грабли? Ведь нет никакой гарантии, что пара/десяток/половина записей не будут удалены.

Соотв. если APPEND FROM не работает - COPY TO тоже вряд-ли что-то даст?
"Медленно и печально" построчно копировать таблицу - могу конечно, но не хочу.

Даже если заменить все поля с "+" на "I:+", то придется вручную проверять: а какой ID у новой записи получился: тот, что идет "автоматом" при APPEND BLANK или тот, что будет присвоен при копировании очередной записи?


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 2 [только новые]







Пост N: 519
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 28.03.17 23:54. Заголовок: Вот что пишет druzus..


Вот что пишет druzus на эту тему: https://groups.google.com/forum/#!searchin/harbour-users/autoinc|sort:relevance/harbour-users/0CxCr8ddaYk/A6yBfPMWr8wJ

On Mon, 09 Feb 2015, elch wrote:

Hi,

In current implementation I blocked assignment to autoinc,
rowver and modtime fields. It interacts with COPY TO and
APPEND FROM commands when such fields are explicitly copied
blocking these operations.
I'll change it when I'll find time to extend RDD transfer
protocol to work with automatically updated fields.
The final version will keep the flowing rules:
1. When records are copied to empty table then original values
of automatically updated fields will be copied too and after
the operation the counter and steep values bound with copied
fields will be transferred from source to destination table.
2. When destination table is not empty then only modtime fields
will be copied. Autoinc and rowver fields in newly added
records will be initialized using destination table counters
and after operation counter and step values won't be
transferred.
I also think about making public RDDI_*/DBI_* actions which will
and unblock manual modification of automatically updated fields.
They will be used in the extended record transfer protocol so
I have to introduce them. Documenting them as public RDD and DB
actions would allow users to make their own modification if they
really need them.

best regards,
Przemek




Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 520
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 29.03.17 00:14. Заголовок: Разобрался. 2015-03..


Разобрался.

2015-03-05 20:46 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
...
; Now DBF* RDDs in Harbour respects the following rules for record
transfer operations (COPY TO / APPEND FROM) with automatically
updated fields:
- COPY TO transfers original values to destination table and
finally copy counters from the source table to destination one
so autoincrement fields in both tables after next append will be
initialized with the same values regardless of number of copied
records - even if only single record is copied then counters in
destination table will inherit next values for new record from
the source table. Also values of RowVer and ModTime fields are
copied from source to destination table and not updated during
transfer operation.
- APPEND FROM works like COPY TO (original field values and then
counters are copied to destination table) if the source table
supports counters and destination table is empty and FLocked()
or opened in exclusive mode.
If source table does not support counters for given fields, i.e.
it is processed by transfer RDD like DELIM or SDF (RDT_TRANSFER)
or destination table is not empty or opened in shared mode and
FLock is not set when APPEND FROM is executed then automatically
updated fields (counters, RowVer, ModTime) are not copied and
initialized with new values like for each new record added to
destination table.

Принимающая таблица должна быть 1) пустая и 2) открыта в EXCLUSIVE (или заблокирована через Flock()).
Проверил. Все гуд.
Может кому пригодится.

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 399
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет