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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 03.07.2009, 06:19   #4  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
365 / 542 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
->
Цитата:
Сообщение от Dron AKA andy Посмотреть сообщение
... После непродолжительных размышлений над оригинальным кодом я заметил некую странность: мы сначала наполняем контейнер названиями полей в SQL-интерпретации через
X++:
dictTable.fieldName(this.field(i), DbBackend::SQL)
, а затем повторно получаем названия тех же полей, но уже чуть видоизмененным способом:
X++:
dictTable.fieldName(this.field(i),dbBackend::Sql,0,fieldNameGenerationMode::FieldListGroupBy)
Буду рад, если кто-нибудь мне объяснит, почему сделано именно так ...
Для MS SQL Server разницы в вызове dictTable.fieldName(...) c параметром fieldNameGenerationMode по-умолчанию или со значением fieldNameGenerationMode::FieldListGroupBy нет никакой(по крайней мере я ее не замечал), а вот для Oracle разница существенная.

В случае, наличия в индексе строкового поля, при вызове dictTable.fieldName(this.field(i),dbBackend::Sql,0,fieldNameGenerationMode::FieldListGroupBy) ядро AX преобразует поля к одному регистру, добавляя вызов substr и nls_lower.

Т.е. в AX 3.0 для СУБД Oracle вызов dictTable.fieldName(this.field(i), DbBackend::SQL) для строкового поля вернет field, а вызов dictTable.fieldName(this.field(i),dbBackend::Sql,0,fieldNameGenerationMode::FieldListGroupBy) - вернет
substr(nls_lower(field), 1, strlen(field)).

В конфигурации АОСа AX4.0 есть параметр -
Database Tuning\AutoGeneration Options\Include SUBSTR and LOWER in all SELECT statements to support Oracle mixed-case systems, который видимо и отвечает за генерацию данного substr и nls_lower.

В итоге, если в таблице есть значения строкового поля 'SSS' и 'sss', данное поле включено в индекс и используемая СУБД Oracle, то замена

X++:
dictTable.fieldName(this.field(i),dbBackend::Sql,0,fieldNameGenerationMode::FieldListGroupBy)
на

X++:
dictTable.fieldName(this.field(i), DbBackend::SQL)
приведет к тому, что при использовании пункта 'Дубликаты' - появится инфолог - 'Дубликатов нет'. А при попытке сделать индекс уникальным, вывалится ошибка, о не возможности его создания, поскольку ядро AX при создании индекса на Oracle использует все те же substr и nls_lower

В связи с этим, привожу немного измененный код(для AX 3.0, аналогичные изменения можно внести и для AX 4.0), который одинаково работает как на SQL, так и на Oracle.

X++:
void showDuplicates()
{
    tableId         tableId         = this.tableid();
    DictTable       dictTable       = new DictTable(tableId);
    boolean         dataPrCompany   = dictTable.dataPrCompany();
    container       fields;
    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;
    ;
    if (dataPrCompany)
        fields += dictTable.fieldname(fieldnum(common,DataAreaId),DbBackend::SQL);
    for (i = 1; i <= numberOfFields; i++)
    {
        fields += dictTable.fieldName(this.field(i), DbBackend::SQL);
    }
    //srf -->
    //if (dataPrCompany)
    //    numberOfFields++;
    //srf <--
    stmtStr = 'select count(*)';
    //srf -->
    if (dataPrCompany)
    {
        stmtStr += ', ' + dictTable.fieldName(fieldnum(Common,DataAreaId),DbBackend::Sql,0,FieldNameGenerationMode::FieldListGroupBy);
    }
    //srf <--
    for (i = 1; i <= numberOfFields; i++)
    {
        stmtStr += ', ' + dictTable.fieldName(this.field(i),dbBackend::Sql,0,fieldNameGenerationMode::FieldListGroupBy);
    }
    stmtStr += ' from ' + dictTable.name(DbBackend::SQL);
    stmtStr += ' group by ';
    //srf -->
    if (dataPrCompany)
    {
        stmtStr += dictTable.fieldName(fieldnum(Common,DataAreaId),DbBackend::Sql,0,FieldNameGenerationMode::FieldListGroupBy);
        if (numberOfFields >= 1)
        {
            stmtStr+= ', ';
        }
    }
    //srf <--
    for (i = 1; i <= numberOfFields; i++)
    {
        if (i > 1)
            stmtStr += ', ';
        stmtStr += dicttable.fieldName(this.field(i),dbBackend::Sql,0,fieldNameGenerationMode::GroupByFieldList);
    }
    //srf -->
    if (dataPrCompany)
        numberOfFields++;
    //srf <--
    stmtStr += ' having count(*) > 1';
    if (numberOfFields > 0)
    {
        stmtStr += ' order by ';
        for (i = 1; i <= numberOfFields; i++)
        {
            if (i > 1)
                stmtStr += ', ';
            stmtStr += int2str(i+1);
        }
        stmtStr += ' desc';
    }
    resultSet = stmt.executeQuery(stmtStr);
    while (resultSet.next())
    {
        resultLineStr = "@SYS283" + strFmt(': %1', resultSet.getString(1));
        for (i = 1; i <= numberOfFields; i++)
        {
            resultField = strLtrim(resultSet.getString(i+1));
            if (i == 1 && dataPrCompany)
                resultField1 = resultField;
            else
                resultLineStr += strFmt(', %1: \'%2\'', conPeek(fields, i), resultField);
        }
        if (dataPrCompany)
            setPrefix(strFmt('%1: %2', conPeek(fields, 1), resultField1));
        info(resultLineStr);
        anyDuplicates = true;
    }
    if (!anyDuplicates)
        info("@SYS68671");
}
P.S. Кстати данную функцию починили в AX2009, а параметр Database Tuning\AutoGeneration Options\Include SUBSTR and LOWER in all SELECT statements to support Oracle mixed-case systems в конфигурации АОСа отсутсвует.
За это сообщение автора поблагодарили: tricky (1).
Теги
aot, ax2009, ax3.0, ax4.0, code access security, security, баг, безопасность, индекс, инструменты, ошибка, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
После перестроения перекрестных ссылок начинает жутко тормозить Add-Ins MironovI DAX: Программирование 4 27.09.2007 13:46
AX4: Кнопка "Сценарий" в паспорте записи Den Ram DAX: Функционал 2 19.04.2007 13:53
Axapta Lessons: Add menu options to the Add-Ins submenu Blog bot DAX Blogs 0 28.10.2006 18:22
Что делает кнопка "Упорядочить" в форме разноски накладной? Bega DAX: Функционал 1 10.01.2006 12:25
Недоступна кнопка "Разноска" YaHooka DAX: Прочие вопросы 1 24.03.2005 16:57

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

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

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