04.06.2009, 08:18 | #1 |
Участник
|
DAX 2009 & UtcDateTime & Primary Key
Доброго времени суток!
DAX 2009 (application version 5.0.1000.52) Наблюдается некоректное поведение функции Global::record2DynaKey, если в первичном ключе таблицы, есть поле типа UtcDateTime, в этом случае строковый ключ строится неправильно, как следствие, использование обратной функции Global::dynaKey2Record, не приводит к ожидаемому результату. Видимо реализация метода Global::record2DynaKey должна быть примерно такой(сделано по аналогии с типом Date) : X++: static str record2DynaKey(Common rec) { tableId tableId = rec.TableId; DictTable dictTable = new DictTable(tableId); indexId indexId = dictTable.indexUnique(); DictIndex dictIndex = dictTable.indexObject(indexId); str buf; int indexCnt; int fieldsInIndex; fieldId fieldId; str any2strLocal(anytype t) { return t; } if (dictIndex.name() == 'RecId') // RecId as index return '['+int2str(fieldnum(Common,RecId))+':'+int642str(rec.RecId)+']'; else { fieldsInIndex = dictIndex.numberOfFields(); for (indexCnt = 1; indexCnt <= fieldsInIndex; indexCnt++) { fieldId = dictIndex.field(indexCnt); buf += '[' + int2str(fieldId) + ':'; switch (typeof(rec.(fieldId))) { case Types::Date: buf += date2str(rec.(fieldId),-1,-1,-1,-1,-1,-1, DateFlags::None); break; //SRF --> case Types::UtcDateTime : buf += datetime2str(rec.(fieldId), DateFlags::None); break; //SRF <-- default: //buf += any2StrLocal(strReplace(rec.(fieldId),' ', '%20')); buf += any2StrLocal(rec.(fieldId)); } buf += ']'; } if (dictIndex.allowDuplicates()) { buf += '['+int2str(fieldnum(Common,RecId))+':'+int642str(rec.RecId)+']'; } } return buf; } X++: private str buildIndexStr(Common record, List listFieldIds) { fieldId fieldId; str ret; TextBuffer thisStr = new TextBuffer(); Integer i, nWords; anytype thisFieldValue; str any2strLocal(anytype t) { return t; } ; enum.reset(); while (enum.moveNext()) { fieldId = enum.current(); switch (typeof(record.(fieldId))) { case Types::Date: ret += date2str(record.(fieldId),-1,-1,-1,-1,-1,-1); listFieldIds.addEnd(fieldId); break; //srf --> case Types::UtcDateTime : ret += datetime2str(record.(fieldId)); listFieldIds.addEnd(fieldId); break; //srf <-- default: thisFieldValue = record.(fieldId); thisStr.setText(any2StrLocal(thisFieldValue)); ret += thisStr.getText(); // Repeat the field ID once per word: nWords = SysSearch::splitIntoWords(thisStr).elements(); for (i = 0; i < nWords; ++i) { listFieldIds.addEnd(fieldId); } } ret += #DELIMITER; } ret += tablelabel; // Search for the table label as well. return ret; } P.S. Во вложении проект, эмитирующий данную ситуацию. В нем 1 таблица, 2 джоба и 2 класса(Global и SysDataSearchIndexBuilder, изменения аналогичны написаным в теме, но закоментарены). job SRF_FindUtcDateTimeTypeInUniqueIndex - выводит список таблиц, в которых в первичном ключе есть поле типа UtcDateTime(в стандарте нашел порядка 10 таких таблиц) job SRF_TestRecord2DynaKey - эмитирует ошибку функции Global::record2DynaKey. Для того, чтобы пронаблюдать данный эффект в импортируемой таблице создайте одну запись, запустите job, затем внесите изменения в Global и вновь запустите job. |
|
|
За это сообщение автора поблагодарили: kashperuk (5). |
04.06.2009, 10:05 | #2 |
Модератор
|
Простите, а что заставило Вас внести Дату в первичный ключ?
С Уважением, Георгий |
|
04.06.2009, 13:56 | #3 |
Administrator
|
Не зная мнения автора по этому вопросу - скажу что это удобная альтернатива RecId (когда на таблице нет другого ключа). Замечу, что это не просто дата, а дата+время.
В свое время, я разбирался с клиент-банком от BankSoft Systems (BSS) - и там в таблицах по выпискам (или платежкам - точно не помню) (софтина локальная, а не веб) именно таким образом сделан первичный ключ. Впоследствии - очень наглядно получается при анализе записи - можно с точностью до миллисекунды определить момент создания записи (кстати, таким образом легко и генерить записи сторонней программой в базе) Конечно, в рамках преобразования даты в строку в аксапте - производительность сказывается не в лучшую сторону. Но это уже совершенно другая тема.
__________________
Возможно сделать все. Вопрос времени |
|
04.06.2009, 14:03 | #4 |
Модератор
|
А-а-а!!! Не убивай меня. Номерные серии для чего придуманы???
С Уважением, Георгий |
|
04.06.2009, 15:03 | #5 |
Administrator
|
Номерные серии - это хорошо. Но когда заполнение производится из кода - то на каждый чих вводить номерные серии (в настройках) тоже тяжело.
Номерные серии не отвечают на вопрос "Когда" Не каждый с ходу догадается (или решит использовать альтернативу) использовать номерные серии - когда есть такое поле. Согласен, что по правильному в Аксапте должны использоваться номерные серии. Но представь себе начинающего консультанта - который ломает голову - где в системе отображается "волшебная" номерная серия "Пакет корреспонденции" Просто до АХ2009 не было поля, содержащего время и дату одновременно. Вот и с появлением новго поля появились новые идеи.
__________________
Возможно сделать все. Вопрос времени |
|
04.06.2009, 15:11 | #6 |
SAP
|
Цитата:
Просто до АХ2009 не было поля, содержащего время и дату одновременно. Вот и с появлением новго поля появились новые идеи.
|
|
04.06.2009, 15:13 | #7 |
Модератор
|
Ох, я бы за такие "идеи"...
Делайте серию "на всякий случай", назначайте ее. Если есть задача встраивать дату - дату лучше встраивать отдельно. Если так уж надо встриавать дату в нумератор - дорабатывайте номерные серии. А ломать себе голову - это и есть работа консультанта. За нее деньги платят. А вот сокровенный смысл включения даты в первичный ключ - не понимаю. С Уважением, Георгий |
|
05.06.2009, 01:26 | #8 |
Administrator
|
Согласен с George Nordic. Применительно к Аксапте следует поступать именно так
__________________
Возможно сделать все. Вопрос времени |
|
05.06.2009, 07:05 | #9 |
Участник
|
Цитата:
X++: indexId indexId = dictTable.indexUnique(); Цитата:
в первичном ключе таблицы
Простите, что ввел в заблуждение первым постом. А с учетом того, что AX сама создает уникальный индекс на таблице Проблема с индексами, если таковой отсутсвует, то и не обязательно, чтобы в AOT на таблице был уникальный индекс. Цитата:
Цитата:
P.S. Например, в стандарте Дата в качестве поля первичного ключа присутствует во многих местах, например, на таблице InventTransPosting(Здесь дата как мне кажется несет определенную смысловую нагрузку, а не просто ради производительности добавлена в индекс, но это опять-таки отдельная тема для разговора) |
|
|
За это сообщение автора поблагодарили: George Nordic (2). |
Теги |
ax2009, dynakey2record, indexunique, record2dynakey, utcdatetime, баг, ошибка |
|
|