FormDataSource中Outer Join属性的一个Bug

郁闷了一天,终于解决了一个问题,再次强烈鄙视Dynamics Ax的文档,很多很奇怪的用法一点文档介绍都没有!!
问题描述:
为了给InventSum表中每个ItemId和InventDimId的组合创建一个属性,又不改变这个表的结构,新建了一张名为InventSumProperty的表,字段描述如下:
ItemId:料品Id
InventDimId:库房维组Id
Property:新增加的属性
增加一个跟表InventSum的连接,连接字段为ItemId和InventDimId
为了展示这些属性,新建了一个Form,由于需要显示某些物料和库存纬度的值,于是InventSum需要跟InventDim表内联,然后再跟InventSumProperty外联。
这样这个Form就有三个数据源
InventSum      JoinSource:空   LinkType:Delayed
InventDim      JoinSource:InventSum      LinkType:InnerJoin
InventSumProperty   JoinSource:InventSum   LinkType:OuterJoin
将某些想展现的东东放到Grid里,本来以为万事大吉了,谁想到让俺着实郁闷了一把,打开窗体时迎接俺的是如下的错误:
无法选择 InventSumExternal (InventSumExternal) 中的记录。该联接在 WHERE 子句中的联接表之间不包含任何链接。
这个提示还真是莫名奇妙,不包含任何连接??明明在表InventSumExternal上加了连接啊......怪哉!
排查过程
以前做过蛮多三个表之间的内联,于是试着InventSumproperty的LinkType改成InnerJoin,果然这样就不报错了!但是这还是不能满足要求,因为如果改成InnerJoin,很多InventSum表中存在但在InventSumProperty中没有对应属性的值将不会显示,这不符合要求。
看了一下是在执行InventSum_ds的ExcuteQuery方法时出错的,用SQL跟踪没有跟踪到任何语句,看来是在语句分析阶段就出错了,没有执行SQL语句。
重载InventSum_ds的ExcuteQuery方法,在Super之前写入一下代码:
None.gif info(InventSum_DS.query().dataSourceNo( 1 ).toString());
最终得到如下SQL语句
None.gif SELECT   *   FROM  InventSum 
None.gif
JOIN   *   FROM  InventDim 
None.gif
WHERE  InventSum.InventDimId  =  InventDim.inventDimId 
None.gif
OUTER   JOIN   *   FROM  InventSumExternal 
None.gif
WHERE  InventSum.ItemId  =  InventSumExternal.ItemId  AND  InventSum.InventDimId  =  InventSumExternal.InventDimId
None.gif
这个语句应该是提交给SQL Server分析的语句,当然这个语句只是个半成品,在SQL Server中不能执行,在X++中也有语法错误。
分别改装成真正的SQL版本和X++版本如下:
SQL版本:
None.gif SELECT   *   FROM  InventSum 
None.gif
INNER   JOIN   InventDim  ON  InventSum.InventDimId  =  InventDim.inventDimId 
None.gif
LEFT   JOIN  InventSumExternal  ON  InventSum.InventDimId  =  InventSumExternal.InventDimId
上面这个语句在SQL Server运行没有任何问题
X++版本:
None.gif static   void  sqlTest(Args _args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    InventSum inventSum;
InBlock.gif    InventDim inventDim;
InBlock.gif    InventSumExternal inventSumExternal;
InBlock.gif    ;
InBlock.gif    
InBlock.gif    SELECT 
* FROM inventSum
InBlock.gif        JOIN 
* FROM inventDim
InBlock.gif        WHERE InventSum.InventDimId 
== InventDim.inventDimId
InBlock.gif             OUTER JOIN 
* FROM inventSumExternal
InBlock.gif             WHERE InventSum.ItemId 
== InventSumExternal.ItemId &&
InBlock.gif                   InventSum.InventDimId 
== InventSumExternal.InventDimId;
InBlock.gif
ExpandedBlockEnd.gif}
运行上面的语句,报出了与采用Form时一样的错!!看来问题出在这上面了,X++编译器在编译这个语句的时候有Bug,不能生成正确的SQL语句!郁闷死了......在这里卡壳了好半天,试来试去,突然想到把OUTER JOIN的顺序移到JOIN前面试试看。
None.gif static   void  sqlTest(Args _args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    InventSum inventSum;
InBlock.gif    InventDim inventDim;
InBlock.gif    InventSumExternal inventSumExternal;
InBlock.gif    ;
InBlock.gif    
InBlock.gif    SELECT 
* FROM inventSum
InBlock.gif        OUTER JOIN 
* FROM inventSumExternal
InBlock.gif             WHERE InventSum.ItemId 
== InventSumExternal.ItemId &&
InBlock.gif                   InventSum.InventDimId 
== InventSumExternal.InventDimId
InBlock.gif             JOIN 
* FROM inventDim
InBlock.gif             WHERE InventSum.InventDimId 
== InventDim.inventDimId;
InBlock.gif 
InBlock.gif
ExpandedBlockEnd.gif}
ft!没想到这样就OK了!真是让人费解啊!
如果能想办法让FormDataSource对应的Query生成的X++查询代码也是OUTERJOIN在前,INNERJOIN在后问题应该就解决了?试着将InventSumExternal_ds挪到InventDim_ds的前面,没有任何作用。。。。。。
这个查询应该是在调用各个数据源的Init方法时构造出来的,前面测试过Init方法的执行顺序,当时还真是让人费解,貌似执行顺序不定,可能先执行这个,也可能后执行那个,并且与DataSource在Form中显示的次序没有关系。突然记起前面测试的时候先后创建的两个Form,用的是同样的两个数据源,结果两个数据源的Init方法调用的顺序正好相反,难道跟刚刚创建DataSource时的顺序有关???
重新创建了一个Form,仍然使用上述三个DataSource,只不过在创建的时候按如下顺序
InventSum,InventSumExternal,InventDim
连接数据源和连接方式仍然按照前面的设定。
NND,居然OK了!!
彻底搞不懂了......
结论:
X++的解释器有bug,如果有两个数据源分别通过InnerJoin和OuterJoin关联到同一个数据源上,那么一定要记得在创建数据源的时候,连接关系为OuterJoin的数据源一定要先于InnerJoin的数据源创建。
那位又问了?要是两个数据源都通过OuterJoin连接到同一个数据源该怎么办?
您老就别难为AX了吧,恐怕这个它压根就没考虑,要不您试试看?

转载于:https://www.cnblogs.com/Farseer1215/archive/2007/01/23/627441.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值