22.12.2015, 09:11 | #1 |
Участник
|
mfp: X++ in AX7: String truncation
Источник: http://blogs.msdn.com/b/mfp/archive/...runcation.aspx
============== Consider this X++ code: CustGroupId id = "012345678901234567890123456789"; //30 chars long; CustGroup custgroup; custGroup.id = id; custGroup.insert; select custGroup where custGroup.id == id; The CustGroupID EDT is defined with a length of 20 characters. In AX 2012 the assignment in the very first line would truncate the string from 30 to 20 characters. The record would be inserted and selected again. In AX7 the CustGroupID EDT is being compiled as the CLR type: string. The consequence being that no truncation occurs in the first line. The truncation happens in the data base layer, as the column can only contain 20 characters. The most significant change is in the select statement. In AX7 no record will be found, as no record has an ID matching the 30-character long ID. Actually; this also happens in AX2012 – when X++ code is compiled as CIL. Is this good or bad? I think it is primarily good. It is good - very good from a performance perspective. X++ is now compiled into CLR and is magnitudes faster than in AX2012. We could have injected a small check to validate and truncate every string upon assignment - at a quite dire cost. In the vast majority of cases the truncation isn't required - string lengths are already enforced, for example on the UI - so we opted for performance. The only issues we discovered by this was in automated testing - like unit tests, where test data defined in code contained too long strings. In reality an implementation problem already in AX2012 - but it didn't surface until now. Once you know this change in behavior, solving the relatively few issues aren't a big deal. THIS POST APPLIES TO MICROSOFT DYNAMICS AX7 TECHICAL PREVIEW; IS PROVIDED AS-IS AND CONFERS NO RIGHTS. ============== Источник: http://blogs.msdn.com/b/mfp/archive/...runcation.aspx
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
13.04.2019, 02:24 | #2 |
Участник
|
Четыре года спустя выяснилось, что все же строки надо обрезать, даже в CIL, и фиг с ней, с производительностью. В самом начале обновленной заметки 2015 года появилась такая фраза:
Цитата:
Update: 5th April 2019: The behavior has changed. Now strings are truncated on assignment.
PHP код:
|
|
|
За это сообщение автора поблагодарили: EVGL (3), trud (2), Logger (7), ax_mct (3), alex55 (1), lvan (2). |
13.04.2019, 11:58 | #3 |
Участник
|
Денис, спасибо.
А есть инфа почему так сделали? Юнит тесты неверно работали? В 2012-й тоже поведение поменялось? |
|
16.04.2019, 02:39 | #5 |
Участник
|
Мне кажется, как раз юнит-тесты все эти годы отрабатывали на ура, и косяки вылезли лишь в реальных проектах. Вроде автор пишет, почему изначально отказ от обрезания значений по EDT был рискованным шагом: допустим, есть у тебя в базе клиентская группа с кодом '0123456789', и пишешь ты код вида
X++: CustGroup custGroup; CustGroupId custGroupId = '0123456789abcdefghij'; // допустим, извне пришло длинное значение select firstonly custGroup where custGroup.CustGroup == custGroupId; if (custGroup.CustGroup == custGroupId) { info('Bingo!'); } |
|
16.04.2019, 11:13 | #6 |
Участник
|
Ну, я как бы это и имел в виду, что работали они неадекватно. Неверно моделировались рабочие примеры.
|
|
29.05.2020, 18:24 | #7 |
Участник
|
Цитата:
Сообщение от gl00mie
В AX2012 и ранее у тебя случается Bingo! Код прекрасно находит запись в CustGroup с кодом '0123456789', потому что длинное значение обрезается на присваивании строковой переменной, и в СУБД уходит параметр SQL-запроса "нужной" длины. А вот в D365O у тебя этот код ничего не находит, потому что в СУБД уходит строка 20 символов, которая никогда не окажется равна полю nvarchar(10).
Только что коллега столкнулся с ситуацией когда в ax4 все работало корректно а в 12-ке нет. Ситуация - find метод на талдычке делает поиск по iso коду из 3 символов. В метод на вызове передали значение 276_1 Значение с кодом 276 в табличке есть. С кодом 276_1 нет и не может быть так как длина строки в столбце 3 символа. В 4-ке код работает корректно - ничего не находит. В 12-ке находит. Так происходит, потому что в 4-ке несмотря на объявление строкового типа из 3 символов в переменной реально могло храниться больше символов. А в 12-ке воткнули везде усечение и оно раньше времени усеклось до 3 символов и значение стало "подходить". В общем видимо 4-ка и 365-я ведут себя одинаково в этом смысле. В 12-ке даже объявление переменной str 1000 не спасает. (в вашем примере X++: str 1000 custGroupId = '0123456789abcdefghij'; // допустим, извне пришло длинное значение Видимо усекается где то при выполнении select. Это совсем ниже пояса как говорится... Последний раз редактировалось Logger; 29.05.2020 в 18:27. |
|