Показать сообщение отдельно
Старый 18.02.2009, 18:24   #10  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Все гораздо проще.
Есть у датасорса в квери (объект QueryBuildDataSource) свойство fetchMode.
По умолчанию оно имеет значение QueryFetchMode::One2Many. Но его можно поставить в значение QueryFetchMode::One2One.

Смысл следующий.
Допустим у нас есть запрос из двух таблиц - шапки и строк. Если fetchMode = QueryFetchMode::One2Many, то getNo(шапки) возвратит курсор шапки только один (первый) раз для всех строк данной шапки.
Т.е. это будет выглядеть так:
X++:
while (queryRun.next())
{
      = queryRun.getNo(1);
     do
     {
           = queryRun.getNo(2);
          .................... // код
     }
     while (queryRun.next());
}
Если же поставить fetchMode в значение QueryFetchMode::One2One (или в 0 что тоже самое) - то Вы получите тот эффект, который ожидаете получить.
Т.е. при каждом вызове queryRun.next() оба курсора будут заполнены данными.

Я не знаю как это связано с производительностью и зачем такая логика. Но она (логика) заложена именно такая.
В исходном сообщении речь шла про группировку, вы наверное не обратили на это внимания... Ну и не важно...

Я про ваше замечание про "странный эффект":
X++:
static void ZVVTestOne2OneMany(Args _args)
{
    Query query = New Query();
    QueryRun queryRun;

    QueryBuildDataSource qbds1;
    QueryBuildDataSource qbds2;

    CustTable       custTable;
    RContractTable  contractTable
    ;

    qbds1 = query.addDataSource(tableNum(CustTable));
    qbds2 = qbds1.addDataSource(tableNum(RContractTable));
    qbds2.relations(true);
    qbds2.fetchMode(QueryFetchMode::One2Many);

    qbds2.addRange(fieldnum(RContractTable,RContractPartnerCode)).value(queryValue("4100"));

    queryRun = New QueryRun(query);

    info(qbds1.toString());

    while (queryRun.next())
    {
        custTable = queryRun.getNo(1);
        contractTable = queryRun.getNo(2);

        info(strFmt("%1 %2", custTable.AccountNum, contractTable.RContractAccount));
    }
}
X++:
SELECT * FROM CustTable JOIN * FROM RContractTable WHERE 0 = RContractTable.RContractPartnerType AND CustTable.AccountNum = RContractTable.RContractPartnerCode AND (((RContractPartnerCode = '4100')))
4100 0080
4100 560/1431
4100 0014
4100 0122
4100 0120
4100 0026
4100 0035
4100 0036
4100 1277/1431
4100 689/1441
DAX30SP3KR3

UPD уточню:
- QueryFetchMode::One2Many можно ставить и у первого и у обоих ДС - ничего не меняется
- попробовал на 40сп2 - то же самое.
Вероятно ваши данные с каких-то старых версий? Или чего в моём примере не хватает чтоб добиться вашего эффекта?
__________________
Zhirenkov Vitaly

Последний раз редактировалось ZVV; 18.02.2009 в 18:35.