您的位置:首页 > 产品设计 > UI/UE

[AX]AX2012开发新特性-outer join中使用QueryFilter

2012-08-15 10:56 411 查看
假设我们有两张表SalesOrder和SalesOrderLine,分别包含如下数据:

SalesOrderID (integer, primary key)

DateAdded (date)

1

2010-01-01

2

2010-02-02

SalesOrderLineID (string, primary key)

Quantity (integer)

SalesOrderID (integer, foreign key)

AA

32

1

BB

67

1

CC

66

1

SalesOrder为主表,SalesOrderLine为子表,通过SalesOrderId链接。

首先用X++的SELECT的OUTER JOIN来挑选纪录:

static void OuterJoinSelectJob3(Args _args)
{
SalesOrder recSalesOrder;
SalesOrderLine recSalesOrderLine;
struct struct4;
;
struct4 = new struct
("int SalesOrderID;"
+ "date DateAdded;"
+ "str SalesOrderLineID;"
+ "int Quantity"
);

while
SELECT
*
from
recSalesOrder
OUTER JOIN recSalesOrderLine
WHERE
recSalesOrder.SalesOrderID == recSalesOrderLine.SalesOrderID
&& recSalesOrderLine.Quantity == 66
{
struct4.value("SalesOrderID", recSalesOrder.SalesOrderID);
struct4.value("DateAdded", recSalesOrder.DateAdded);
struct4.value("SalesOrderLineID", recSalesOrderLine.SalesOrderLineID);
struct4.value("Quantity", recSalesOrderLine.Quantity);
info(struct4.toString());
}
}


得到的结果是:

(SalesOrderID:1; DateAdded:2010/1/1; SalesOrderLineID:"CC"; Quantity:66)
(SalesOrderID:2; DateAdded:2010/2/2; SalesOrderLineID:""; Quantity:0)


即数量等于66的SalesOrderLine对应的SalesOrder,还包含一个没有任何SalesOrderLine的SalesOrder。

类似的还可以使用Query在QueryBuildRange针对数量添加条件来获取纪录,在AOT创建Query QrySalesAndLines:



使用Query来获取纪录:

// X++
static void QueryBuildRange5rJob(Args _args)
{
Query query2;
QueryBuildDataSource qbDataSource3;
QueryRun queryRun4;
QueryBuildRange qbRange6;

SalesOrder recSalesOrder;
SalesOrderLine recSalesOrderLine;

struct struct5;
;
struct5 = new struct
("int SalesOrderID;"
+ "date DateAdded;"
+ "str SalesOrderLineID;"
+ "int Quantity"
);

query2 = new Query("QrySalesAndLines");
qbDataSource3 = query2.dataSourceName("SalesOrderLine_1");

// This QueryBuildRange restriction is in the ON clause of
// the OUTER JOIN in the ANSI SQL Select statement that is
// generated by the AOS for the underlying database system.
qbRange6 = qbDataSource3.addRange
(fieldNum(SalesOrderLine, Quantity));
qbRange6.value("66");

queryRun4 = new QueryRun(query2);
while (queryRun4.next())
{
recSalesOrder = queryRun4.getNo(1);
recSalesOrderLine = queryRun4.getNo(2);

struct5.value("SalesOrderID", recSalesOrder.SalesOrderID);
struct5.value("DateAdded", recSalesOrder.DateAdded);
struct5.value("SalesOrderLineID", recSalesOrderLine.SalesOrderLineID);
struct5.value("Quantity", recSalesOrderLine.Quantity);
info(struct5.toString());
}
}


得到的结果和前面SELECT OUTER JOIN是一样的,SQL TRACE可以看到执行的SQL语句是:

-- ANSI SQL
SELECT
*
from
SalesOrder as tSO

LEFT OUTER JOIN
SalesOrderLine as tSOL
ON
(tSO.SalesOrderID = tSOL.SalesOrderID
and
tSOL.Quantity = 66
)
;


注意这里的Quantity=66是作用在ON上的,即使子表中没有满足条件的纪录,主表也会包含在结果中,对应的子表字段使用子表字段的默认值填充,那么有办法过滤掉这些空值的左表纪录吗?在AX2012中新增了QueryFilter类,来看看它是如何运作的:

// X++
static void QueryFilter4fJob(Args _args)
{
Query query2;
QueryBuildDataSource qbDataSource3;
QueryRun queryRun4;

// The QueryFilter class was not in Microsoft Dynamics AX 2009.
QueryFilter qFilter7;

SalesOrder recSalesOrder;
SalesOrderLine recSalesOrderLine;

struct struct5;

struct5 = new struct
("int SalesOrderID;"
+ "date DateAdded;"
+ "str SalesOrderLineID;"
+ "int Quantity"
);

query2 = new Query("QrySalesAndLines");
qbDataSource3 = query2.dataSourceName("SalesOrderLine_1");

// This QueryFilter restriction is in the WHERE clause of
// the ANSI SQL Select statement that is generated by the AOS
// for the underlying database system.
qFilter7 = query2.addQueryFilter(qbDataSource3, "Quantity");
qFilter7.value("66");

queryRun4 = new QueryRun(query2);
while (queryRun4.next())
{
recSalesOrder = queryRun4.getNo(1);
recSalesOrderLine = queryRun4.getNo(2);

struct5.value("SalesOrderID", recSalesOrder.SalesOrderID);
struct5.value("DateAdded", recSalesOrder.DateAdded);
struct5.value("SalesOrderLineID", recSalesOrderLine.SalesOrderLineID);
struct5.value("Quantity", recSalesOrderLine.Quantity);
info(struct5.toString());
}
}


得到的结果是:

(SalesOrderID:1; DateAdded:2010/1/1; SalesOrderLineID:"CC"; Quantity:66)


就只有quantity=66的SalesOrderLine对应的SalesOrder一条纪录了,对应的SQL语句是:

-- ANSI SQL
SELECT
*
from
SalesOrder as tSO

LEFT OUTER JOIN
SalesOrderLine as tSOL
ON
(tSO.SalesOrderID = tSOL.SalesOrderID
)
where
tSOL.Quantity = 66
;


注意对数量的过滤条件放在了WHERE后,得到的结果集必须满足条件Quantity=66,所以包含子表字段默认值的纪录就被过滤掉了,这就是QueryFitler的作用。

更多内容参见MSDN:http://msdn.microsoft.com/en-us/library/gg881181.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: