4

我在 MDX 中的“YYYYMMDD”格式字符串上应用与日期相关的函数时遇到了一些问题。例如,如果我在下面有这个查询:

with 
    member foo as WEEKDay("2013-03-21")
select
    foo on 0
from 
    [Some Cube]

它将在 SSMS 中为 foo 正确输出“5”。但是,如果我将第二行更改为:

   member foo as WEEKDay("20130321")

不幸的是,它会抛出“类型不匹配”错误。

所以我想要做的是将字符串转换为一些可识别的日期格式,然后在其上应用函数。最简单方法的任何想法,例如使用现有功能?

请注意,该字符串实际上是从运行 MDX 的任何多维数据集中的成员输入的。所以字符串格式可以被识别,例如“YYYY-MM-DD”。所以硬编码的字符串转换算法可能不行。

4

3 回答 3

1

主题太旧了,但也许这可能对某人有所帮助。技术相当粗鲁,但可扩展。

with 
    member foo_false as WeekDay("20130321")
    member foo_true as WeekDay("2013-03-21")
    member foo_brute as 
    case when IsError(WeekDay("20130321"))=False then WeekDay("20130321") else
        case
        /* YYYYMMDD */
        when 
        IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
        and IsError(WeekDay(Left("20130321",4)+'-'+Right(Left("20130321",6),2)+'-'+Right("20130321",2)))=False
            then WeekDay(Left("20130321",4)+'-'+Right(Left("20130321",6),2)+'-'+Right("20130321",2))

        /* DDMMYYYY */
        when 
        IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
        and IsError(WeekDay(Right("20130321",4)+'-'+Right(Left("20130321",4),2)+'-'+Left("20130321",2)))=False
            then WeekDay(Right("20130321",4)+'-'+Right(Left("20130321",4),2)+'-'+Left("20130321",2))

        /* MMDDYYYY */
        when 
        IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
        and IsError(WeekDay(Right("20130321",4)+'-'+Left("20130321",2)+'-'+Right(Left("20130321",4),2)))=False
            then WeekDay(Right("20130321",4)+'-'+Left("20130321",2)+'-'+Right(Left("20130321",4),2))

        /* Unsupported Message */
        else "Unsupported Format" end
    end
select
    {foo_false,foo_true,foo_brute} on 0
from 
    [DATA Cube]

在“不支持”之前将支持的格式添加到末尾,使用任何输入字符串而不是"20130321".

但最简单的方法是在插入到 MDX 之前使用另一层(例如 SQL 函数 CONVERT),如果可能的话,当然可以。

于 2015-01-27T15:10:46.663 回答
0

vba 函数isDate可用于检查传递的日期是否格式正确。如果不是,则首先使用dateserial和格式化它mid并使用它们。

with 
member foo as "20130321"

member bar as   
iif(vba!isdate(foo) = TRUE, 
    WEEKDay(foo), //--if the date is already well formatted, it can be used
    WEEKday(vba!dateserial(vba!mid(foo, 0, 4), vba!mid(foo, 5, 2), vba!right(foo, 2))))
select
    bar on 0
from 
    [some cube]

编辑

上面的代码可以修改以适应其他检查,例如MMDDYYYYor DDMMYYYY,但在很多情况下,引擎不可能直观地知道传递的值是否在YYYYMMDDDDorDDMMYYYYMMDDYYYY中。以字符串为例1111111

这可以很容易地采用任何日期格式,因为它是一个有效的日期,无论你如何打破它。

我建议您有另一个成员也可以存储日期格式。这样看这个成员,就可以解析字符串。

例如

with 
member foo as 
//  "20130321" //YYYYMMDD
//  "03212013"//MMDDYYYY
"21032013"//DDMMYYYY

MEMBER dateformat as "ddmmyyyy"



member bar as   
iif(vba!isdate(foo) = TRUE, 
    WEEKDay(foo), 
    IIF(dateformat = "yyyymmdd", //YYYYMMDD
        WEEKday(vba!dateserial(vba!mid(foo, 0, 4), vba!mid(foo, 5, 2), vba!right(foo, 2))), 
        IIF(dateformat = "mmddyyyy", //MMDDYYYY
            WEEKday(vba!dateserial(right(foo, 4), vba!mid(foo, 0, 2), vba!mid(foo, 3, 2))),
            IIF(dateformat = "ddmmyyyy", //DDMMYYYY
                WEEKday(vba!dateserial(right(foo, 4), vba!mid(foo, 3, 2), vba!mid(foo, 0, 2))),
                null
               )
            )
        )
    )

select
    bar on 0
from 
    [aw cube]
于 2015-08-04T06:55:47.603 回答
0

FooMember这里是一个 int,代表一个yyyyMMdd日期,我可以使用以下代码将其转换为 Date

   =Format(CDate(Left(CSTR(Fields!FooMember.Value),4)
   + "-" + Mid(CSTR(Fields!FooMember.Value), 5, 2)
   + "-" + Right(CSTR(Fields!FooMember.Value), 2)),
   "dd/MM/yyyy")

使用以下代码在多维数据集中使用它

 Format(CDate(Left([Measures].[FooMember],4)
 + "-" + Mid([Measures].[FooMember], 5, 2)
 + "-" + Right([Measures].[FooMember], 2)),"yyyy/MM/dd")
于 2021-01-28T14:06:09.973 回答