|
21.10.2005, 10:48 | #1 |
Moderator
|
Как изменить id полей?
Здравствуйте!
Собственно сабж. Возникло непонятное расхождение между fieldId в одной из таблиц на рабочей и тестовой базах. Соответственно, поднятая на рабочую форма, основанная на этой таблице, показала какую-то ерунду (на форме, как известно, привязка контролов идет по fieldId). Экспорт-импорт со значениями идентификаторов не исправляет id существующих полей. Можно, конечно, удалить с тестовой базы все поля с неверными id, импортировать таблицу со значениями идентификаторов из рабочей базы и затем создать недостающие поля заново, подготовив тем самым правильную структуру таблицы. В процессе этих манипуляций, естественно, теряются данные из полей, что для тестовой базы некритично. Но возникла идея решить проблему путем замены fieldId непосредственно, без пересоздания полей. Сейчас это праздное любопытство, но, вполне возможно, когда-нибудь поможет решить более серьезную проблему. Пока я смог накопать только то, что простое программное изменение id поля в таблицах UtilIdElements и SQLDictionary приводит следующему: id в репозитарии меняется, но поле теряет все свои свойства, в том числе и тип. Поэтому вопрос к общественности: решаема ли такая задача?
__________________
Андрей. |
|
21.10.2005, 12:42 | #2 |
Administrator
|
А не надо заменять fieldId. Правильный fieldId хранится у вас в приложении. А вот подстроить под это дело базу - можно легко. Удалите из таблички SQLDictionary все записи, касающиеся данной таблички (фильтр по tabId), и нажмите Администрирование-Периодические операции-SQLАдминистрирование. Выберите нужную табличку(которую грохали в SQLDictionary) и нажмите кнопку Таблицы-Проверка/синхронизация. Табличка SQLDictionary воссоздастся с уже правильным fieldId (который соответствует АОТу), и все... Воспользутйесь принципом - что правильный тот fieldId, который в АОТе, а не в SQLDictionary.
PS Данные не пропадут. Сначала воссоздастся SQLDictionary, а затем пройдет синхронизация (по уже заведомо правильным Id-шникам)
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: Logger (5). |
21.10.2005, 12:54 | #3 |
Moderator
|
То, что SQLDictionary восстановится по АОТ - это хорошо. Но в моем случае есть 2 АОТ, в которых таблица имеет разные fieldId для одних и тех же полей. И надо добиться одинаковой структуры. Т.е. fieldId менять тем или иным способом.
__________________
Андрей. |
|
21.10.2005, 12:58 | #4 |
Member
|
Посмотрите поиск. Если у вас 3.0, то поможет экспорт-импорт с сохранением идентификатторов объектов.
__________________
С уважением, glibs® |
|
21.10.2005, 13:03 | #5 |
Moderator
|
Процитирую сам себя:
Цитата:
Сообщение от Dron AKA andy
Экспорт-импорт со значениями идентификаторов не исправляет id существующих полей.
__________________
Андрей. |
|
21.10.2005, 13:23 | #6 |
Member
|
Вы экспортировали в файл, меняли в текстовом редакторе, ID и импортировали обратно? Остался старый?
__________________
С уважением, glibs® |
|
21.10.2005, 13:36 | #7 |
Moderator
|
Именно.
__________________
Андрей. |
|
21.10.2005, 15:02 | #8 |
Участник
|
Цитата:
Пока я смог накопать только то, что простое программное изменение id поля в таблицах UtilIdElements и SQLDictionary приводит следующему: id в репозитарии меняется, но поле теряет все свои свойства, в том числе и тип.
__________________
Axapta v.3.0 sp5 kr2 |
|
21.10.2005, 15:35 | #9 |
Moderator
|
Экспериментирую повторно. То слетают, то не слетают. Попробуйте использовать несколько полей разных типов и менять id в произвольном порядке.
__________________
Андрей. |
|
21.10.2005, 16:19 | #10 |
Участник
|
Цитата:
Сообщение от Dron AKA andy
Экспериментирую повторно. То слетают, то не слетают. Попробуйте использовать несколько полей разных типов и менять id в произвольном порядке.
X++: static void Job37(Args _args) { UtilIdElements ue_Table; UtilIdElements ue_Fields; SQLDictionary SQLDict; ; select firstonly ue_Table where ue_Table.recordType == UtilElementType::Table && ue_Table.name == "Table13"; ttsbegin; if (ue_Table) while select forupdate ue_Fields order by id desc where ue_Fields.recordType == UtilElementType::TableField && ue_Fields.ParentId == ue_Table.id { select forupdate firstonly SQLDict where SQLDict.TabId == ue_Table.id && SQLDict.FieldId == ue_Fields.id; ue_Fields.id += 13; ue_Fields.update(); if (SQLDict) { SQLDict.FieldId = ue_Fields.id; SQLDict.Update(); } } ttscommit; }
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Logger (2). |
20.05.2009, 17:52 | #11 |
Участник
|
Цитата:
Сообщение от AndyD
Вот тестовый джоб
X++: static void Job37(Args _args) { UtilIdElements ue_Table; UtilIdElements ue_Fields; SQLDictionary SQLDict; ; select firstonly ue_Table where ue_Table.recordType == UtilElementType::Table && ue_Table.name == "Table13"; ttsbegin; if (ue_Table) while select forupdate ue_Fields order by id desc where ue_Fields.recordType == UtilElementType::TableField && ue_Fields.ParentId == ue_Table.id { select forupdate firstonly SQLDict where SQLDict.TabId == ue_Table.id && SQLDict.FieldId == ue_Fields.id; ue_Fields.id += 13; ue_Fields.update(); if (SQLDict) { SQLDict.FieldId = ue_Fields.id; SQLDict.Update(); } } ttscommit; } Слетает куча мест в приложении, которая ссылается на поле. Формы, мапы (sic!), EDT. Очень аккуратно надо менять, проверяя нет ли ссылок. |
|
21.05.2009, 08:38 | #12 |
Участник
|
Моё мнение, всё это какое-то шаманство.
Я обычно делаю перенос без Id-ков они сами создаются системой. dev->test->work. Ну и пусть они отличаються. Может я на dev 10 раз создавал и 10 раз удалял один и тот же объект. Главное я знаю на рабочей они правильные. Раз в какой-то период(месяц, две недели) надо просто попросить админа выровнять прилаги в обратном порядке. work->test->dev. И Id-ки станут везде хорошие. Заодно мож где-то мусор залежался, смоет.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
21.10.2005, 15:57 | #13 |
Участник
|
Цитата:
Сообщение от Dron AKA andy
Возникло непонятное расхождение между fieldId в одной из таблиц на рабочей и тестовой базах.
Цитата:
Сообщение от Dron AKA andy
форма, основанная на этой таблице, показала какую-то ерунду
Если 2 AOT разные, причем, не по делу - выкиньте один из них, оставшийся разнесите на обе системы. После синхронизации все будет одинаковое. С уважением, itfs. |
|
21.10.2005, 16:07 | #14 |
Moderator
|
Цитата:
Сообщение от itfs
Если 2 AOT разные, причем, не по делу - выкиньте один из них, оставшийся разнесите на обе системы.
Помниться на одном проекте один человек сделал именно так ... В результатет были потеряны 2 моих разработки, которые я отказался делать заново и они так и не были никогда сделаны ... |
|
21.10.2005, 16:21 | #15 |
Участник
|
Цитата:
Сообщение от kvan
Серьезное заявление!
Помниться на одном проекте один человек сделал именно так ... В результатет были потеряны 2 моих разработки, которые я отказался делать заново и они так и не были никогда сделаны ... 2 Dron AKA andy: понятно, в глюки я верю ... просто не увидел проблемы в том, что id разные. С уважением, itfs. PS. Да, самое, ради чего собственно писал, я боюсь что в общем случае требуемый id может быть занят, поэтому все же лично предпочел бы подобрать концы и оставить одну копию AOTа. Последний раз редактировалось itfs; 21.10.2005 в 16:31. |
|
21.10.2005, 16:11 | #16 |
Moderator
|
Цитата:
Сообщение от itfs
Ни разу не сталкивался, хотя первые пол года практики именно так и переносил проекты.
О выкидывании речи не идет, можно и на тестовой добиться правильной структуры, но с потерей данных. А потом спокойно импортировать на рабочую, и там уже ничего не потеряется. Я рассуждаю о гипотетическом случае, когда необходимо по максимуму сохранить данные, и возможность произвольно изменять id полей могла бы помочь. Проблемы как таковой нет, есть желание поэкспериментировать в этом направлении, либо воспользоваться наработками других участников.
__________________
Андрей. |
|
21.10.2005, 17:07 | #17 |
Administrator
|
Цитата:
Сообщение от Dron AKA andy
Я рассуждаю о гипотетическом случае, когда необходимо по максимуму сохранить данные, и возможность произвольно изменять id полей могла бы помочь.
Классический пример - перенос таблицы с уже вбитыми в нее данными в другой слой (LedgerTrans )
__________________
Возможно сделать все. Вопрос времени |
|
21.10.2005, 17:13 | #18 |
Участник
|
Цитата:
Перестройка SQLDictionary в соответствии с новыми id-шниками ВСЕГДА сохраняет данные
__________________
Axapta v.3.0 sp5 kr2 |
|
21.10.2005, 22:44 | #19 |
Administrator
|
Цитата:
Сообщение от AndyD
Что имеется в виду? При синхронизиции, если изменился ID поля, оно удаляется, а затем создается заново. Соответственно при этом данные теряются
Цитата:
Сообщение от sukhanchik
Удалите из таблички SQLDictionary все записи, касающиеся данной таблички (фильтр по tabId), и нажмите Администрирование-Периодические операции-SQLАдминистрирование. Выберите нужную табличку(которую грохали в SQLDictionary) и нажмите кнопку Таблицы-Проверка/синхронизация. Табличка SQLDictionary воссоздастся с уже правильным fieldId (который соответствует АОТу), и все... Воспользутйесь принципом - что правильный тот fieldId, который в АОТе, а не в SQLDictionary.
PS Данные не пропадут. Сначала воссоздастся SQLDictionary, а затем пройдет синхронизация (по уже заведомо правильным Id-шникам)
__________________
Возможно сделать все. Вопрос времени |
|
21.10.2005, 17:45 | #20 |
Moderator
|
В общем, вроде нашел решение.
Вот джоб, которым тестировал: Код: static void Tutorial_ChangeFieldId(Args _args) { UtilIdElements uie; SQLDictionary dict; ; ttsbegin; select forupdate uie where uie.name == "Field2" && uie.parentId == tableNum(Tutorial_ChangeFieldId); if (!uie) warning("Запись в UtilIdElements не найдена"); else { uie.id = 50005; uie.update(); } // appl.dbSynchronize(tableNum(Tutorial_ChangeFieldId), false); // select forUpdate dict // where dict.tabId == tableNum(Tutorial_ChangeFieldId) && dict.fieldId == fieldNum(Tutorial_ChangeFieldId, Field2); // if (!uie) // warning("Запись в SQLDictionary не найдена"); // else // { // dict.fieldId = 50005; // dict.update(); // } ttscommit; } НО: если тупо после этого сделать синхронизацию таблицы - о чудо, все восстановилось! Id поменялся, данные в таблице остались. Абсолютно интуитивно непонятный механизм - смотрим на какую-то фигню (UNKNOWN), после синхронизации получаем конфетку То, что закомментировал, оказалось ненужным. Программная синхронизация таблицы не помогает, нужно почему-то обязательно через АОТ делать. Так что решение таково: программно изменяем IDшники полей в UtilIdElements и делаем синхронизацию таблицы. Вуаля! Спасибо всем, принявшим участие в эксперименте.
__________________
Андрей. |
|