2

I am trying to write a query that retrieves an item based on ItemId or item barcode.

This is using x++, Dynamics AX 2012 R2

select firstOnly * from inventTable
where (inventTable.ItemId == _upc || inventItemBarcode.itemBarCode == _upc)
outer join inventItemBarcode 
where inventItemBarcode.itemId == inventTable.ItemId;

When this is translated into sql it comes out as...

FROM  INVENTTABLE T1 LEFT 
OUTER 
JOIN INVENTITEMBARCODE T2 ON (((T2.PARTITION=?) 
    AND (T2.DATAAREAID=?)) 
    AND (T1.ITEMID=T2.ITEMID)) 
WHERE (((T1.PARTITION=?) 
    AND (T1.DATAAREAID=?)) 
    AND (T1.ITEMID=?))

You can see that is is totally omitting the OR condition in the last line.

I tried writing the query like this

    select firstOnly * from inventTable
    outer join inventItemBarcode 
    where
        //join
        inventItemBarcode.itemId == inventTable.ItemId
        //ilc
        && (inventTable.ItemId == _upc
        || inventItemBarcode.itemBarCode == _upc);

But it puts the OR condition in the outer join ON and then returns me the first row in the InventTable.

Does anyone know how to make this work in X++?

Danielg
  • 2,669
  • 1
  • 22
  • 17
  • I think there is something else wrong, because in the SQL statement of your first query, there is no condition on InventItemBarcode.itemBarCode shown. Are you sure that is the sql statement of your first query? – FH-Inway Jun 26 '14 at 07:48
  • That's what comes out of the profiler. Like I said the condition is totally missing when it gets to sql. – Danielg Jun 26 '14 at 16:40

1 Answers1

3

If using AX 2012 you will have to use Query and QueryRun instead, then add your or-expression as a query expression using addQueryFilter.

static void Job117(Args _args)
{
    str search = "5705050765989";
    QueryRun qr = new QueryRun(new Query());
    QueryBuildDataSource ds1 = qr.query().addDataSource(tableNum(InventTable));
    QueryBuildDataSource ds2 = ds1.addDataSource(tableNum(InventItemBarcode));
    str qstr1 = '((%1.%2 == "%5") || (%3.%4 == "%5"))';
    str qstr2 = strFmt(qstr1, ds1.name(), fieldStr(InventTable,ItemId), 
                       ds2.name(), fieldStr(InventItemBarcode,ItemBarCode),
                       queryValue(search));
    qr.query().addQueryFilter(ds1, fieldStr(InventTable,ItemId)).value(qstr2);
    ds2.joinMode(JoinMode::OuterJoin);
    ds2.relations(true);
    info(qstr2);
    info(ds1.toString());
    while (qr.next())
        info(strFmt("%1", qr.getNo(1).RecId));
}

In prior AX versions you can make a view, then query the view using a query expressions by using the addRange method.

Jan B. Kjeldsen
  • 17,817
  • 5
  • 32
  • 50
  • Yes I finally came to the same conclusion. It's too bad it can't be done in the query syntax. Thank you for your help. – Danielg Jul 03 '14 at 16:04