update_recordset降级的问题

AX中update_recordset降级问题
本文探讨了Microsoft Dynamics AX 4.0中update_recordset在特定条件下无法正确降级的问题,特别是在处理字符串和容器类型字段时出现的异常行为。

<<Microsoft Inside Dynamics AX4.0>>的第十七章中在介绍批操作符update_recordset时提到在几种情况下可能会导致update_recordset降级,变成逐条更新,降级后的update_recordset会按照while select语句的处理方式完成更新,并举了如下例子:

None.gifstatic void UpdateSizes(Args _args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    InventSize inventSize;
InBlock.gif    ;
InBlock.gif    ttsbegin;
InBlock.gif        update_recordset inventSize
InBlock.gif        setting description 
= 'This size is for item PB-Metal Shade'
InBlock.gif        where inventSize.ItemId 
== 'PB-Metal Shade';
InBlock.gif    ttscommit;
InBlock.gif
ExpandedBlockEnd.gif}
由于表InventSize没有满足使update_recordset降级的任何一个条件,所以上述语句在执行的时候将执行批处理操作,执行的SQL语句如下:
None.gif版本: Microsoft Dynamics 4.0 (内部版本号 2163)
None.gif数据库: Microsoft SQL Server
None.gifSQL 语句: UPDATE INVENTSIZE SET DESCRIPTION
=?,RECVERSION=? WHERE ((DATAAREAID=?) AND (ITEMID=?)) [ID=386, 已重用=否]
这没有任何问题,inventsize中相应产品的描述信息被更改。
我们让该表满足使update_recordset降级的一个条件,比如重载一下update方法,然后更改一下UpdateSizes方法中的description的值(因为如果本次更新的值跟原表中相应记录的值一样,while select只执行select语句,并不会执行更新语句)
None.gifstatic void UpdateSizes(Args _args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    InventSize inventSize;
InBlock.gif    ;
InBlock.gif    ttsbegin;
InBlock.gif        update_recordset inventSize
InBlock.gif        setting description 
= 'update_recordset test'
InBlock.gif        where inventSize.ItemId 
== 'PB-Metal Shade';
InBlock.gif    ttscommit;
InBlock.gif
ExpandedBlockEnd.gif}
理论上应该降级成while select 语句完成更新,可是实际上并没有执行更新操作,查看执行的SQL语句,只有一条select语句
None.gif版本: Microsoft Dynamics 4.0 (内部版本号 2163)
None.gif数据库: Microsoft SQL Server
None.gifSQL 语句: SELECT A.INVENTSIZEID,A.ITEMID,A.NAME,A.RECVERSION,A.RECID,A.DESCRIPTION FROM INVENTSIZE A WITH( INDEX(I_1616ITEMSIZEIDX)) WHERE ((DATAAREAID
=?) AND (ITEMID=?)) [ID=360, 已重用=是]
这个蛮让人费解,把上述语句改成while select语句:
None.gifstatic void UpdateSizes(Args _args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    InventSize inventSize;
InBlock.gif    ;
InBlock.gif    ttsbegin;
InBlock.gif        
while select forupdate inventSize
InBlock.gif        where inventSize.ItemId 
== 'PB-Metal Shade'
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            inventSize.Description 
= 'update_recordset test';
InBlock.gif            inventSize.update();
ExpandedSubBlockEnd.gif        }

InBlock.gif    ttscommit;
InBlock.gif
ExpandedBlockEnd.gif}
执行了两条SQL语句:
None.gif数据库: Microsoft SQL Server
None.gifSQL 语句: SELECT A.INVENTSIZEID,A.ITEMID,A.NAME,A.RECVERSION,A.RECID,A.DESCRIPTION FROM INVENTSIZE A WITH( INDEX(I_1616ITEMSIZEIDX)) WHERE ((DATAAREAID
=?) AND (ITEMID=?)) [ID=10, 已重用=否]

None.gif版本: Microsoft Dynamics 4.0 (内部版本号 2163)
None.gif数据库: Microsoft SQL Server
None.gifSQL 语句: 
UPDATE INVENTSIZE SET DESCRIPTION=?,RECVERSION=WHERE ((((DATAAREAID=?) AND (ITEMID=?)) AND (INVENTSIZEID=?)) AND (RECVERSION=?)) [ID=11, 已重用=否]
可以正常更新.
这应该说明问题出在update_recordset没有成功降级成while select 语句。
尝试更新了一下其他字段:
None.gifstatic void UpdateSizes(Args _args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    InventSize inventSize;
InBlock.gif    ;
InBlock.gif    ttsbegin;
InBlock.gif        update_recordset inventSize
InBlock.gif        setting name 
= 'update_recordset test'
InBlock.gif        where inventSize.ItemId 
== 'PB-Metal Shade';
InBlock.gif    ttscommit;
InBlock.gif
ExpandedBlockEnd.gif}
上面的例子更新了inventSize的name字段,该方法执行了两条SQL语句,一条查询一条更新。
说明顺利完成了降级为while select的操作,正常更新了相应记录。
综上所述,造成updae_recordset不能正常降级的原因应该是字段类型的问题,对照了一下description和name两个字段,它们的基类型都是string,只不过name是stringsize属性为60的string,而description是stringsize属性为memo的string类型,两者在SQL Server2005中对应的类型分别为nvarchar(60)和nText。
尝试把字段description对应EDT的stringsize改成某个长度而不是memo,update_recordset就可以顺利降级了。
测试了其他的类型int,real,date,time,enum,container,其中int,real,date,time,enum没有问题,在测试container的时候郁闷的事情又发生了,给inventsize添加一个container类型的字段containertest,重载inventsize的update方法,执行如下方法:
None.gifstatic void UpdateSizes(Args _args)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    InventSize inventSize;
InBlock.gif    ;
InBlock.gif    ttsbegin;
InBlock.gif        update_recordset inventSize
InBlock.gif        setting containertest 
= [2,4]
InBlock.gif        where inventSize.ItemId 
== 'PB-Metal Shade';
InBlock.gif    ttscommit;
InBlock.gif
ExpandedBlockEnd.gif}
执行后AOS当掉了,查看事件查看器,在系统日志中得到如下信息:
None.gif事件类型:    错误
None.gif事件来源:    Service Control Manager
None.gif事件种类:    无
None.gif事件 ID:    
7034
None.gif描述:
None.gif服务 Dynamics Server$
01-Dynamics 意外停止。这发生了 3 次。
None.gif
None.gif有关更多信息,请参阅在 http:
//go.microsoft.com/fwlink/events.asp 的帮助和支持中心。
None.gif

在控制命令行里用sc query aos$01查看WIN32_EXIT_CODE ,得到如下结果:
SERVICE_NAME: aos$01
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN))

        WIN32_EXIT_CODE    : 1067  (0x42b)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
运行net helpmsg 1067查看具体的帮助信息得到如下信息:
进程意外终止
这个信息没啥帮助。
查看应用程序日志:

None.gif事件类型:    错误
None.gif事件来源:    Application Error
None.gif事件种类:    (
100)
None.gif事件 ID:    
1000
None.gif计算机:    ADSERVER
None.gif描述:
None.gif错误应用程序 Ax32Serv.exe,版本 
4.0.2163.0,错误模块 Ax32Serv.exe,版本 4.0.2163.0,错误地址 0x00322810
None.gif
None.gif有关更多信息,请参阅在 http:
//go.microsoft.com/fwlink/events.asp 的帮助和支持中心。
None.gif
数据:
None.gif
000041 70 70 6c 69 63 61 74   Applicat
None.gif
000869 6f 6e 20 46 61 69 6c   ion Fail
None.gif
001075 72 65 20 20 41 78 33   ure  Ax3
None.gif
001832 53 65 72 76 2e 65 78   2Serv.ex
None.gif
002065 20 34 2e 30 2e 32 31   e 4.0.21
None.gif
002836 33 2e 30 20 69 6e 20   63.0 in 
None.gif
003041 78 33 32 53 65 72 76   Ax32Serv
None.gif
0038: 2e 65 78 65 20 34 2e 30   .exe 4.0
None.gif
0040: 2e 32 31 36 33 2e 30 20   .2163.0 
None.gif
004861 74 20 6f 66 66 73 65   at offse
None.gif
005074 20 30 30 33 32 32 38   t 003228
None.gif
005831 30                     10      
None.gif

通过系统和应用程序的日志还真整不明白到底是什么原因造成的服务意外终止。

综上所述,AX在处理update_recordset降级的时候有两个问题:
1.如果字段类型是string且stringsize属性为memo,则只会执行select动作,不会执行更新动作;
2.如果字段类型是container类型,则会引发AOS服务的意外终止。

换了几个环境测试都存在上述问题,按理说原书的作者应该测试过书中所举的例子,不知道是不是还需要配置什么信息,如果配置都正确的话应该就是AX平台的bug或者局限性了。

转载于:https://www.cnblogs.com/Farseer1215/archive/2007/05/08/738761.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值