在MDX中将“YYYYMMDD”格式字符串转换为日期?

问题描述:

亲爱的朋友们,在MDX中将“YYYYMMDD”格式字符串转换为日期?

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

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

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

member foo as WEEKDay("20130321") 

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

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

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

非常感谢!

干杯

主题太旧了,但也许这可以帮助别人。技术非常粗暴,但可扩展。

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),如果可能的话。

可以使用vba函数isDate来检查传递的日期是否格式良好。如果不是,则首先使用dateserialmid格式化并使用它们。

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] 

EDIT

上面的代码可以被修改以适应其它的检查如MMDDYYYYDDMMYYYY,但事情是它在很多情况下是不可能的发动机直观地知道,如果通过的值是YYYYMMDDDDDDMMYYYYMMDDYYYY。以字符串为例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]