AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 15.02.2019, 07:07   #1  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
643 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Баг в SysDictIndex
Актуальная версия аксапты: AX2012 R3, модификация совместима с более ранними версиями.
Еще в прошлом году нашел баг неверного составления SQL-запроса для поиска записей дубликатов, которые присутствуют в индексе.
Функция вызывается в контекстном меню по конкретному индексу.
Все бы хорошо, но в более ранних версиях, например в АХ4 она в принципе не работает.
Во-первых из-за того, что вызывается на клиенте.
Во-вторых, абсолютно неверно составляется запрос. Функцию невозможно было вызвать ни при каких условиях. Непонятно, как вообще она прошла в production.
В-третьих, хоть она и была исправлена в 2012, однако с некоторыми отключенными полями запрос все-равно формировался с ошибками.
В-четвертых, хотелось бы поменять порядок на более удобный - по убыванию количества дубликатов.
X++:
void showDuplicates()
{
    // > inserted by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    #define.DataAreaNo(2)
    // < inserted by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    tableId         tableId         = this.tableid();
    DictTable       dictTable       = new DictTable(tableId);
    boolean         dataPrCompany   = dictTable.dataPrCompany();
    Counter         numberOfFields  = this.numberOfFields();
    Counter         i;
    str             stmtStr;
    str             resultLineStr;
    str             resultField;
    str             resultField1;
    UserConnection  con             = new UserConnection();
    Statement       stmt            = con.createStatement();
    ResultSet       resultSet;
    boolean         anyDuplicates   = false;
    DictField       dField;
    str             tableNameWithSchema;
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    Map             fields          = new Map(Types::Integer, Types::String);
    MapEnumerator   enumerator;
    Counter         fieldsCount     = #DataAreaNo;
    str             fieldList;
    str             orderList;
    int             key;
    str             fieldName;
    // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    //container       fields;
    //int             enabledFields[];
    //Counter         enabledFieldCounter;
    //SqlStatementExecutePermission ssep;
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    ;
    if (dataPrCompany)
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    {
        fields.insert(fieldsCount, dictTable.fieldName(fieldnum(Common, DataAreaId), DbBackend::Sql));
        fieldsCount++;
    }
    // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    //    fields += dictTable.fieldName(fieldnum(Common,DataAreaId),DbBackend::Sql);
    //
    //enabledFieldCounter = 0;
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates

    for (i = 1; i <= numberOfFields; i++)
    {
        dField = new DictField(tableId, this.field(i));
        // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
        if (dField.isSql() && dfield.id() != fieldnum(Common, DataAreaId))
        {
            fields.insert(fieldsCount, dictTable.fieldName(this.field(i), DbBackend::Sql));
            fieldsCount++;
        }
        // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
        //if( dField.isSql() == false )
        //    continue;
        //++enabledFieldCounter;
        //enabledFields[enabledFieldCounter] = i;
        // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    }
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    stmtStr = 'select count(*), ';
    enumerator = fields.getEnumerator();
    while (enumerator.moveNext())
    {
        if (any2int(enumerator.currentKey()) != #DataAreaNo)
        {
            fieldList += ', ';
            orderList += ', ';
        }
        fieldList += any2str(enumerator.currentValue());
        orderList += int2str(any2int(enumerator.currentKey()));
    }

    stmtStr += fieldList;
    // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    //for (i = 1; i <= enabledFieldCounter; i++)
    //{
    //    fields += dictTable.fieldName(this.field(enabledFields[i]), DbBackend::Sql);
    //}
    //
    //stmtStr = 'select count(*)';
    //for (i = 1; i <= enabledFieldCounter; i++)
    //{
    //    stmtStr += ', ' + dictTable.fieldName(this.field(enabledFields[i]),DbBackend::Sql,0,FieldNameGenerationMode::FieldListGroupBy);
    //}
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates

    tableNameWithSchema = xSession::getDbSchema();
    if (tableNameWithSchema != '')
        tableNameWithSchema += '.'+ dictTable.name(DbBackend::Sql);
    else
        tableNameWithSchema = dictTable.name(DbBackend::Sql);

    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    stmtStr += strfmt(' from %1 group by %2', tableNameWithSchema, fieldList);
    // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    //stmtStr += ' from ' + tableNameWithSchema;
    //stmtStr += ' group by ';
    //for (i = 1; i <= enabledFieldCounter; i++)
    //{
    //    if (i > 1)
    //        stmtStr += ', ';
    //    stmtStr += dictTable.fieldName(this.field(enabledFields[i]),DbBackend::Sql,0,FieldNameGenerationMode::GroupByFieldList);
    //}
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates

    stmtStr += ' having count(*) > 1';
    if (numberOfFields > 0)
    {
        // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
        stmtStr += ' order by 1 desc, ';
        stmtStr += orderList;
        // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
        //stmtStr += ' order by ';
        //for (i = 1; i <= enabledFieldCounter; i++)
        //{
        //    if (i > 1)
        //        stmtStr += ', ';
        //    stmtStr += int2str(enabledFields[i]+1);
        //}
        // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
        stmtStr += ' desc';
    }

    // dangerous API mitigation
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    new SqlStatementExecutePermission(stmtStr).assert();
    // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
    //ssep =  new SqlStatementExecutePermission(stmtStr);
    //ssep.assert();
    // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates

    // BP Deviation Documented
    resultSet = stmt.executeQuery(stmtStr);

    while (resultSet.next())
    {
        resultLineStr = "@SYS283" + strfmt(': %1', resultSet.getString(1));
        // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
        enumerator.reset();
        while (enumerator.moveNext())
        {
            key         = any2int(enumerator.currentKey());
            fieldName   = any2str(enumerator.currentValue());
            resultField = strLRTrim(resultSet.getString(key));
            if (dataPrCompany && key == #DataAreaNo)
                resultField1 = resultField;
            else
                resultLineStr += strfmt(", %1: '%2'", fieldName, resultField);
        }
        // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
        //for (i = 1; i <= numberOfFields; i++)
        //{
        //    resultField = strltrim(resultSet.getString(enabledFields[i]+1));
        //    if (i == 1 && dataPrCompany)
        //        resultField1 = resultField;
        //    else
        //        resultLineStr += strfmt(', %1: \'%2\'', conpeek(fields, enabledFields[i]), resultField);
        //}
        // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates

        if (dataPrCompany)
            // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
            setprefix(strfmt("%1: %2", fieldstr(Common, DataAreaId), resultField1));
            // > modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates
            //setprefix(strfmt('%1: %2', conpeek(fields, 1), resultField1));
            // < modified by dech, 26.11.2018, PPO_CHG0031936_InventDimDuplicates

        info(resultLineStr);
        anyDuplicates = true;
    }
    if (!anyDuplicates)
        info("@SYS68671");

}
Изображения
 
__________________
// no comments
За это сообщение автора поблагодарили: Logger (5), SRF (3).
Теги
duplicates, index, sysdictindex, баг, индекс, ошибка

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Баг или фича - неожиданное поведение метода xRecord.data() Pandasama DAX: Программирование 3 21.03.2016 13:01
AX 2012 Пересчет единиц измерения - баг или фича? Kabardian DAX: Функционал 3 25.02.2014 11:00
Баг или не баг? Murlin DAX: Программирование 53 14.09.2013 18:52
Баг при печати налогового кода petr DAX: Программирование 0 25.03.2009 16:33
баг в 2.5. Будьте осторожнее с символом "_" подчеркивание levsha DAX: Программирование 5 07.12.2004 12:26

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:37.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.