Показать сообщение отдельно
Старый 18.06.2009, 08:27   #14  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
376 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
... За что отвечает значение 256, я не знаю.
Думаю, что наверное Вы уже знаете, про данный параметр, но кто-то может и не знать.

Если заглянуть в класс SQLDataBaseInit, то в определении класса можно увидеть макрос #define.transidsPerCompany(256), откуда можно сделать предположение, это значение отвечает за генерацию TransactionId в разрезе компании(проверил на DAX 4.0, так оно и оказалось ), про 256 можно сказать так :
Цитата:
256: This session is using “TransactionsID per company”
Посмотрел как используется значение 4 параметра INDEX в AX.
Цитата:
4 : Allow DESC on index components
in CREATE INDEX statement.
Как оказалось, используется это значение по-умолчанию только с СУБД Oracle, так же как и значение 128 (#define.indexOraStrFunctional(128)).
Выскажу предположение, что это может быть как-то связано с тем, что до версии Oracle 8i ключевое слово DESC игнорировалось в инструкции CREATE INDEX(т.е. возможно, что нужны еще какие-то доп. условия, чтобы параметр desc подставлялся в инструкцию create index)

Оффтоп : Пока смотрел как используется значение 4, обнаружил интересный момент(багофича). В AX 3.0 и AX 4.0 есть класс SqlscanSQLIndex, который используется при проверки\синхронизации таблиц(Администрирование\Периодические операции\SQL Администрирование).
У данного класса есть метод isDescendingOrder, который по логике вещей должен определять порядок сортировки поля в индексе, однако он всегда возвращает false, несмотря на то, что использует массив descendingOrder, просто разработчики видимо забыли что, его нужно тоже заполнять

Причем не заполняется он ни для Oracle, ни для MS SQL Server. Более того, для MS SQL Server - для определения структуры индекса используется хранимая процедура sp_helpindex, которая в случае если поле в индексе имеет порядок сортировки desc возвращает после него "(-)", что тоже никак не учтено .
Т.е. к примеру - у вас есть таблица, у нее есть индекс, содержащий поле field1. Теперь если вы не посредственно на SQL Server для данного поля в индексе выставите сортировку DESC, а потом запустите проверку\синхронизацию таблицы, то в отчете будет выведено, что поле индекса в БД имеет имя field1(-), а в AOT field1, хотя изменился только порядок сортировки. Ниже приведен код для DAX 4.0, исправляющий данную ситуацию(тестировал на SQL 2005), изменения нужно внести в метод sqlServerGetIndexInfo класса SqlscanSQLIndex:
X++:
private void sqlServerGetIndexInfo()
{
    Statement       stmt      = con.createStatement();
    Statement       stmt1     = con.createStatement();
    ResultSet       resultSet;
    str             columns;
    str             columnToken;
    str             realIndexes[ #DEFINE.MAX_INDEX_PER_TABLE ];
    int             nbrRealIndexes = 0;
    str             queryString;
    str             result2;
    str             indexName;
    int             len, columnNo, i;
    int             strCount;
    boolean         sysTraceActive = xSession::getSysTraceActive();
    SqlStatementExecutePermission ssep;
    //srf -->
    boolean         isDescOrder;
    str             descToken = "(-)";
    //srf <--
    ;
    xSession::setSysTraceActive(true);
    queryString = 'SELECT name FROM sysindexes WHERE indid>0 AND indid<255 AND id=object_id(\'' + sQLIndexTable + '\')'+
                  ' AND INDEXPROPERTY(id, name, \'IsStatistics\') = 0';
    //Assert executeQuery a Dangerous APi
    ssep = new SqlStatementExecutePermission ( queryString );
    ssep.assert();
    //BP Deviation Documented
    resultSet = stmt.executeQuery( queryString );
    while (resultSet.next() )
    {
        nbrRealIndexes++;
        realIndexes[nbrRealIndexes] = resultSet.getString( 1 );
    }
    if (!nbrRealIndexes)
        return;
    //revert assert
    CodeAccessPermission::revertAssert();
    queryString = '/*SP*/ exec sp_helpindex ' + sQLIndexTable;
    //Assert executeQuery a Dangerous APi
    ssep = new SqlStatementExecutePermission ( queryString );
    ssep.assert();
    //BP Deviation Documented
    resultSet = stmt.executeQuery( queryString );
    while( resultSet.next() )
    {
        indexName = resultSet.getString( 1 );
        for (i=1;i<=nbrRealIndexes;i++)
        {
            if (realIndexes[i] == indexName) break;
        }
        if (i<=nbrRealIndexes)  /* not a statistics index */
        {
            result2 = resultSet.getString( 2 );
            this.completeIndex();
            this.addIndex(indexName);
            isUnique[idxCnt]    = (strscan(result2, 'unique', 0, strlen(result2)) ? true : false );
            isCluster[idxCnt]   = (strscan(result2, 'clustered', 0, strlen(result2)) ? true : false );
            if (isCluster[idxCnt] && strscan(result2, 'nonclustered', 0, strlen(result2)))
                isCluster[idxCnt] = false;
            isPrimary[idxCnt] = (strscan(result2, 'primary key', 0, strlen(result2)) ? true : false );
            columns       = resultSet.getString( 3 );
            len           = strlen( columns );
            strCount      = 1;
            columnNo      = 0;
            while( strCount <= len )
            {
                columnToken = '';
                //srf -->
                isDescOrder = false;
                //srf <--
                while( strCount <= len && substr( columns, strCount, 1 ) != ',' && substr( columns, strCount, 1 ) != ' ' )
                {
                    columnToken += substr( columns, strCount, 1 );
                    strCount++;
                }
                //srf -->
                if (Global::strEndsWith(columnToken, descToken))
                {
                    isDescOrder = true;
                    columnToken = substr(columnToken, 1, strlen(columnToken) - strlen(descToken));
                }
                //srf <--
                if( this.generalFieldHandling( columnToken, columnNo ) )
                {
                    fldCnt++;
                    columnNo++;
                    fieldNames[fldCnt] = columnToken;
                    fieldNo[fldCnt]    = columnNo;
                    //srf -->
                    descendingOrder[fldCnt] = isDescOrder;
                    //srf <--
                }
                while( strCount <= len && substr( columns, strCount, 1 ) == ',' || substr( columns, strCount, 1 ) == ' ' )
                    strCount++;
            }
        }
    }
    this.completeIndex();
    xSession::setSysTraceActive(sysTraceActive);
}
После данного изменения при попытке проверки\синхронизации увидим вполне логичную надпись о том, что есть различия в порядке сортировки поля field1

Кстати, в AX 2009 - данный класс отсутсвует совсем, а проверка и синхронизация таблиц, была вынесена на уровень ядра.
За это сообщение автора поблагодарили: mazzy (2), Logger (2).