Форум » [x]Harbour » Как модифицировать таблицу с AUTOINC полем ? » Ответить

Как модифицировать таблицу с AUTOINC полем ?

Sergy: Добрый день. Много лет использовал такой алгоритм модификации таблиц: [pre2] 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 ... ... [/pre2]И буквально сегодня столкнулся с собственным разгильдяйством. Модифицировал справочник, в котором одно из полей - "чистый" autoincrement: {"id","+",4,0}. В исходной таблице были удалены пара записей, соответственно после APPEND соответствующие ID "поплыли". Ситуацию конечно исправил, заменив поле на "I:+" с автоматическим поиском соответсвтий по другим полям и добавлением пары пустых записей. Разумеется, теперь поставил в TableUpdate() заглушку, отменяющую преобразования, если в исходной таблице будет найдено поле с типом "+". Если, вдруг забуду... Но вот читаю усиленно доки по Harbour, вспоминаю "классические" команды Clipper и не очень понимаю, как вообще, в принципе, поменять структуру таблиц, в которых есть "настоящие" AUTOINC поля, чтобы не наступить на те-же самые грабли? Ведь нет никакой гарантии, что пара/десяток/половина записей не будут удалены. Соотв. если APPEND FROM не работает - COPY TO тоже вряд-ли что-то даст? "Медленно и печально" построчно копировать таблицу - могу конечно, но не хочу. Даже если заменить все поля с "+" на "I:+", то придется вручную проверять: а какой ID у новой записи получился: тот, что идет "автоматом" при APPEND BLANK или тот, что будет присвоен при копировании очередной записи?

Ответов - 2

Sergy: Вот что пишет 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

Sergy: Разобрался. 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()). Проверил. Все гуд. Может кому пригодится.



полная версия страницы