Цитата:
Сообщение от
sukhanchik
Итак:
Да, спасибо за пример, он подтвердил высказанные мною выше подозрения:
(в вашем джобе добавил
X++:
info (qbds1.toString());
info (qbds2.toString());
info (qbds3.toString());
) для наглядности. Результаты:
оба One2Many:
X++:
SELECT * FROM CustTrans
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SQL: (CustTrans) SELECT ... FROM CUSTTRANS A WHERE (SUBSTR(NLS_LOWER(DATAAREAID),1,7)=NLS_LOWER(:in1))
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.INVOICE),1,41),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)
000003_181 - - !
000003_181 - 000001_045 - !
000003_181 - - BYR !
CustTable One2One, Currency One2Many:
X++:
SELECT * FROM CustTrans JOIN * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SQL: (CustTrans,CustTable) SELECT ... FROM CUSTTRANS A,CUSTTABLE B
WHERE (SUBSTR(NLS_LOWER(A.DATAAREAID),1,7)=NLS_LOWER(:in1)) AND ((SUBSTR(NLS_LOWER(B.DATAAREAID),1,7)=NLS_LOWER(:in2)) AND (SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)=SUBSTR(NLS_LOWER(B.ACCOUNTNUM),1,41)))
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41),A.TRANSDATE,SUBSTR(NLS_LOWER(A.VOUCHER),1,41)
000003_181 - 000001_045 - !
000003_181 - 000001_045 - BYR !
CustTable One2Many, Currency One2One:
X++:
SELECT * FROM CustTrans JOIN * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SQL: (CustTrans,Currency) SELECT ... FROM CUSTTRANS A,CURRENCY B
WHERE (SUBSTR(NLS_LOWER(A.DATAAREAID),1,7)=NLS_LOWER(:in1)) AND ((SUBSTR(NLS_LOWER(B.DATAAREAID),1,7)=NLS_LOWER(:in2)) AND (SUBSTR(NLS_LOWER(A.CURRENCYCODE),1,7)=SUBSTR(NLS_LOWER(B.CURRENCYCODE),1,7)))
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.INVOICE),1,41),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)0
00003_181 - - BYR !
000003_181 - 000001_045 - BYR !
оба One2One:
X++:
SELECT * FROM CustTrans JOIN * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum JOIN * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SQL: (CustTrans,CustTable,Currency) SELECT ... FROM CUSTTRANS A,CUSTTABLE B,CURRENCY C
WHERE (SUBSTR(NLS_LOWER(A.DATAAREAID),1,7)=NLS_LOWER(:in1)) AND ((SUBSTR(NLS_LOWER(B.DATAAREAID),1,7)=NLS_LOWER(:in2)) AND (SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)=SUBSTR(NLS_LOWER(B.ACCOUNTNUM),1,41)))
AND ((SUBSTR(NLS_LOWER(C.DATAAREAID),1,7)=NLS_LOWER(:in3)) AND (SUBSTR(NLS_LOWER(A.CURRENCYCODE),1,7)=SUBSTR(NLS_LOWER(C.CURRENCYCODE),1,7)))
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41),A.TRANSDATE,SUBSTR(NLS_LOWER(A.VOUCHER),1,41)
000003_181 - 000001_045 - BYR !
Как видите, запросы к БД отсылаются в этих случаях по разному, как я говорил, вероятно Аксапта "оптимизирует" таким образом сложный запрос.
Насколько я понял, данный эффект происходит только в том случае, когда идёт
непоследовательное соединение датасорсов! Только в этом случае Аксапта начинает "оптимизировать" (как в примере, естественно датасорсов при этом всегда больше двух, как вы верно подметили

) и тогда нужно либо указывать fetchMode=One2One, чтоб запрос к БД был один и тогда можно пользоваться стандартным циклом по квериРун, как обычно. Либо добавлять сложные конструкции с проверкой смены "папы" последством
record.Changed(). Если же порядок соединения последовательный, то fetchMode никакого влияния не оказывает, можете сами проверить поменяв местами CustTable & CustTrans и прицепив, соответсвенно, Currency ко второму DS.
Вот! Так что будьте осторожны и учитывайте данную особенность!
ЗЫ Ещё из интересных особенностей данного поведения: Аксаптовский SQL-Trace не ловит подчинённые запросы к БД при такой оптимизации.

Их можно увидеть только в трэйсе на уровне БД...