Добрый день.
Много лет использовал такой алгоритм модификации таблиц:
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 или тот, что будет присвоен при копировании очередной записи?