Участник
Регистрация: 28.11.2005
Адрес: Москва
|
Глюки в Query с разными типами Join (в т.ч. NonExistsJoin) к одной таблице
Есть несколько компаний, которые "торгуют" между собой через intercompany, и внешние контрагенты, которые торгуют с этими компаниями. Необходимо вывести в отчет проводки только по этим внешним контрагентам, сгруппировав проводки по одному и тому же контрагенту в разных компаниях по внешнему коду. Т.е. внешний контрагент может в разных компаниях называться по-разному, но внешний код у него везде будет одинаковый. Так вот, чтобы отфильтровать контрагентов из справочника поставщиков, которые завязаны на внутренние компании, решил сделать, если упрощенно, примерно следующее:
PHP код:
select *
from vendtrans v
join vendtable t on v.dataareaid = t.dataareaid and
v.accountnum = t.accountnum
join extcodevaluetable e on t.dataareaid = e.dataareaid and
t.recid = e.extcoderelationrecid and
e.extcoderelationtableid = 505 and
e.extcodeid = 'vendExtCodeId'
left join gatewayorgref r on v.dataareaid = r.dataareaid and
v.accountnum = r.refid and
r.reftype = 2
left join gatewayorganization o on r.dataareaid = o.dataareaid and
r.gatewayorgid = o.gatewayorgid and
o.active = 1 and
o.intercompanyorg = 1
where o.gatewayorgid is null
Здесь 'vendExtCodeId' - название внешнего кода для таблицы поставщиков, 505 == tablenum(VendTable), 2 == SysActionRefTypes::Vend, 1 == NoYes::Yes, всякие лишние группировки и выборки полей для простоты опущены. В Аксапте это все реализовано через Query, таблицы Gateway* цепляются через NonExistsJoin. Так вот, в SQL это все прекрасно отрабатывает, но когда дело доходит до Query, то вылезает непонятный глюк: либо не работает фильтр по GatewayOrganization, либо не выбирается VendTable и, соотв., внешний код - в зависимости от того, какую таблицу первой цеплять к VendTrans. Для тестирования написал небольшой job'ик, просьба посмотреть, у одного ли меня такие глюки, и посоветовать, что с этим делать При запуске job спрашивает, в каком порядке цеплять таблицы, в зависимости от этого результат у меня разный X++: static void testJoins(Args _args)
{
VendTrans vt;
VendTable vtbl;
ExtCodeValueTable extcvt;
QueryRun qr;
Query query = new Query();
QueryBuildDataSource qbds, qbdsT;
void joinGatewayOrg()
{
// filter out intercompany contragents
qbds = qbdsT.addDataSource(tablenum(GatewayOrgRef));
qbds.joinMode(JoinMode::NoExistsJoin);
qbds.fetchMode(QueryFetchMode::One2One);
qbds.addLink(fieldnum(VendTrans, AccountNum), fieldnum(GatewayOrgRef, RefId));
qbds.addRange(fieldnum(GatewayOrgRef, RefType)).value(queryValue(SysActionRefTypes::Vend));
qbds = qbds.addDataSource(tablenum(GatewayOrganization));
qbds.fetchMode(QueryFetchMode::One2One);
qbds.addLink(fieldnum(GatewayOrgRef, GatewayOrgId), fieldnum(GatewayOrganization, GatewayOrgId));
qbds.addRange(fieldnum(GatewayOrganization, InterCompanyOrg)).value(queryValue(NoYes::Yes));
qbds.addRange(fieldnum(GatewayOrganization, Active)).value(queryValue(NoYes::Yes));
}
void joinExtCodeValue()
{
ExtCodeId extCodeId;
;
extCodeId = (select firstonly ExtCodeId from ExtCodeTable
where ExtCodeTable.ExtCodeTableId == tablenum(VendTable)).extcodeId;
info(strfmt(@"For table '%1' ExtCodeId = '%2'", tablestr(VendTable), extCodeId));
// join vendtable p on v.accountnum = p.accountnum
qbds = qbdsT.addDataSource(tablenum(VendTable));
qbds.joinMode(JoinMode::InnerJoin);
qbds.fetchMode(QueryFetchMode::One2One);
qbds.relations(false);
qbds.addLink(fieldnum(VendTrans, AccountNum), fieldnum(VendTable, AccountNum));
// join extcodevaluetable e on p.tableid = e.extCodeRelationTableId and
// p.recid = e.extCodeRelationRecId and e.extcodeid = ExtCodeId
qbds = qbds.addDataSource(tablenum(ExtCodeValueTable));
qbds.fetchMode(QueryFetchMode::One2One);
qbds.addLink(fieldnum(VendTable, RecId), fieldnum(ExtCodeValueTable, ExtCodeRelationRecId));
qbds.addRange(fieldnum(ExtCodeValueTable, ExtCodeRelationTableId)).value(queryValue(tablenum(VendTable)));
qbds.addRange(fieldnum(ExtCodeValueTable, ExtCodeId)).value(extCodeId);
}
;
// select * from vendtrans v
qbdsT = query.addDataSource(tablenum(VendTrans));
qbdsT.addSortField(fieldnum(VendTrans, AccountNum));
qbdsT.addSortField(fieldnum(VendTrans, TransDate));
if (Box::yesNo(@"NonExists join first?", DialogButton::Yes) == DialogButton::Yes)
{
joinGatewayOrg();
joinExtCodeValue();
} else
{
joinExtCodeValue();
joinGatewayOrg();
}
qr = new QueryRun(query);
while(qr.next())
{
vt = qr.get(tablenum(VendTrans));
vtbl = qr.get(tablenum(VendTable));
extcvt = qr.get(tablenum(ExtCodeValueTable));
info(strfmt("%1 %2 name='%3', extCode='%4' %5", vt.TransDate, vt.AccountNum, vtbl.Name,
extcvt.ExtCodeValue, (vt.Invoice ? vt.Invoice : vt.Txt)));
}
} Может, я вообще все неправильно делаю, и надо фильтровать как-то иначе?..
Axapta 3.0 SP5 KR2, SQL Server 2005 SP1
|