【问题标题】:Dynamics AX 2012 Complex QueryBuild ObjectDynamics AX 2012 复杂 QueryBuild 对象
【发布时间】:2015-02-10 17:31:24
【问题描述】:

试图过滤 AX 中的特定数据范围并遇到问题。

这就是我想要做的,用伪代码..

(start >= now-30 && (end == null || end >= now-30))
||
(end >= now-30 && (start == null || start >= now-30))
||
(start >= now-30 && end >= now-30)

这是我尝试的方法

类声明

QueryBuildRange filterDates;

DS 初始化方法

filterDates=this.query().dataSourceName('LogTable').addRange(fieldNum(LogTable,startDateTime));    
filterDates=this.query().dataSourceName('LogTable').addRange(fieldNum(LogTable,endDateTime));    

DS 执行方法

filterDates.value(strFmt("(%1 >= %3 && (%2 == %4 || %2 >= %3)) || (%2 >= %3 && (%1 == %4 || %1 >= %3)) || (%1 >= %3 && %2 >= %3)", fieldStr(LogTable, startDateTime), fieldStr(LogTable, endDateTime), currentTimeMinus30Mins, DateTimeUtil::minValue()));

AX 似乎几乎忽略了我输入的所有完整查询。

谢谢

【问题讨论】:

  • 试试 'info(query().XML());'在将语句传递给 QueryRun 对象以查看它吐出什么之前的语句?返回的 XML 是可读的伪 SQL。

标签: sql axapta x++ dynamics-ax-2012


【解决方案1】:

如果你的伪代码中的逻辑是正确的,我仍然可以看到你的 DS EXECUTEQUERY METHOD 中的一些缺陷:

  • 整个表达式必须用括号括起来。
  • 每个子表达式必须包含在自己的括号中。
  • DateTimeUtil::toStr(...) 不见了。

尝试如下更改您的代码:

filterDates.value(strFmt("(((%1 >= %3) && ((%2 == %4) || (%2 >= %3))) || ((%2 >= %3) && ((%1 == %4) || (%1 >= %3))) || ((%1 >= %3) && (%2 >= %3)))",
                        fieldStr(LogTable, startDateTime),
                        fieldStr(LogTable, endDateTime),
                        DateTimeUtil::toStr(currentTimeMinus30Mins),
                        DateTimeUtil::toStr(DateTimeUtil::minValue())));

你应该可以简化一下:

filterDates.value(strFmt("(((%1 >= %3) || (%1 == %4)) && ((%2 >= %3) || (%2 == %4)) && !((%1 == %4) && (%2 == %4)))",
                        fieldStr(LogTable, startDateTime),
                        fieldStr(LogTable, endDateTime),
                        DateTimeUtil::toStr(currentTimeMinus30Mins),
                        DateTimeUtil::toStr(DateTimeUtil::minValue())));

另外,我看不出有任何理由在 DS INIT METHOD 中初始化 filterDates 两次。您实际上可以在此范围内使用不同的字段,它不必是 startDateTime 或 endDateTime:

filterDates = SysQuery::findOrCreateRange(this.query().dataSourceTable(tableNum(LogTable)), fieldNum(LogTable, RecId));

P.S.我不太记得应该如何在此类表达式中使用 utcDateTime 值 - 据我所知,DateTimeUtil::toStr(...) 应该可以工作。

【讨论】:

    【解决方案2】:

    我认为你的逻辑有缺陷,这可能是它不起作用的原因!

    我猜你想用两个日期时间字段startend 进行时间点搜索,如果没有结束,end 是空白的。

    要搜索 30 天前有效的记录,需要的条件是:

    (start <= now-30 && (end == null || end >= now-30))
    

    在数据源的executeQuery中实现:

    public void executeQuery()
    {
        QueryBuildDataSource qds = this.query().dataSourceTable(tableNum(LogTable));        
        SysQuery::findOrCreateRange(qds, fieldNum(LogTable,StartDateTime)).value('..'+queryValue(currentTimeMinus30Mins));
        SysQuery::findOrCreateRange(qds, fieldNum(LogTable,EndDateTime)).value('"",'+queryValue(currentTimeMinus30Mins+'..');
        super();
    }
    

    以上适用于日期字段,我认为它也适用于日期时间字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多