Показать сообщение отдельно
Старый 06.02.2025, 11:43   #28  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,971 / 3267 (116) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Метод linkPhysicalTableInstance_MRC содержал ошибку, которая приводила к тому, что не всегда работало как надо.

Исправленная версия
X++:
/// <summary>
/// _thisRecord начинает ссылаться на данные _record
/// Метод сделан как замена стандартному xRecord.linkPhysicalTableInstance() чтобы обойти его ошибки.
/// подробнее см.
/// [url=https://axforum.info/forums/showthread.php?p=443440#post443440]Ax 2012 строит запрос с ошибкой в синтаксисе[/url]
/// [url=https://axforum.info/forums/showthread.php?p=437193#post437193]Работа с TempDB-таблицами[/url]
/// </summary>
/// <param name="_thisRecord">
/// Таблица, у которой переназначаются данные.
/// </param>
/// <param name="_record">
/// Таблица, на чьи данные теперь будут ссылаться
/// </param>
/// <returns>
/// Успешно или нет
/// </returns>
/// <remarks>
///
/// </remarks>

// CustCrmClientActivityDocTmp_MRC_Fix "Исправляем ошибку WITH ( INDEX(i105707_I_105707PHONEIDX_(null)))", PKoz3 22.01.2025

public static boolean linkPhysicalTableInstance_MRC(Common _thisRecord, Common _record)
{
    Common      tmpRecord;
    str         tableName;

    boolean     ret;
    ;

    tableName = _record.getPhysicalTableName();

    if (!tableName) // значит табличку не сохраняли еще
    {
        tmpRecord = _record.data();

        // см. RetailUtilities::getPhysicalTableName(_record);
        // Force instantiation of Temp DB table.

        // select generateonly firstOnly RecId from _record; // так не работает. Sql имя резервируется,
        // но потом useExistingTempDBTable() не подхватывает это имя

        // а так работает. Видимо потому, что физически табличка в БД создается.
        // _record.doInsert();
        // _record.doDelete();

        select firstOnly RecId from _record; // так тоже работает, но меньше телодвижений !

        tableName = _record.getPhysicalTableName();

        _record.data(tmpRecord);
    }

    ret = _thisRecord.useExistingTempDBTable(tableName);

    // ret = _thisRecord.linkPhysicalTableInstance(_record); // такой вариант вместо вызова useExistingTempDBTable() не работает
    // проверяли предположение что проблема была в том, что вызвали linkPhysicalTableInstance для непроинициализированного параметра
    // в котором еще нет физического имени таблицы (не в этом ли корень проблем ? Поэтому сперва принудительно инициализируем буфер,
    // чтобы вызов linkPhysicalTableInstance гарантированно шел на проинициализированном TempDb буфере)

    // Оказалось что нет - ошибка с хинтом воспроизводится после любого вызова linkPhysicalTableInstance
    // т.е. сам по себе linkPhysicalTableInstance - какой то кривой и что-то портит в xRecord, поэтому лучше
    // избегать вызовов linkPhysicalTableInstance

    return ret;
}