Showing posts with label mdx. Show all posts
Showing posts with label mdx. Show all posts

Thursday, March 22, 2012

Class not registered error while using Stored procedure

Hi,

I had registered a COM DLL (CogUdf32.dll) as Assembly under the Adventure Works DW.

When i tried executing a method from it through MDX query:

SELECT

{ FILTER([Customer].[Customer].AllMembers, CogUdf32.CogInStr([Customer].[Customer].CurrentMember.Name,"USA") > 0) }

ON AXIS(0)

FROM [Adventure Works];

I am getting following error:

The following system error occurred: Class not registered .

Any pointers are welcome.

Thanks and Regards,
Santosh.

COM UDF's are turned off by default due to the security concerns.

It is better practice and it is safer to write your UDF's in .NET language and compile them as assemblies. But if you still need your COM UDF go to the "SQL Surface Area Configuration" tool avaliable through the start menu shortcut and enable COM UDF for Analysis Services.

Edward.
--
This posting is provided "AS IS" with no warranties, and confers no rights.

|||

MY UDF's are written in .NET language. I am able to add them as COM DLL under Assemblies. But when i try to use the functions, i am getting these errors:

MDX:
SELECT
{ FILTER([Measures].[Sales Amount], CogUdf32.CogInStr([Measures].[Sales Amount],"*", 0) > 0) }
ON AXIS(0)
FROM [Adventure Works]

Error: The following system error occurred: Class not registered .

MDX:
SELECT
{ FILTER([Measures].[Sales Amount], CogUdf32.CCogRExp.CogInStr([Measures].[Sales Amount],"*", 0) > 0) }
ON AXIS(0)
FROM [Adventure Works]

Error: Query (2, 37) The '[CogUdf32].[CCogRExp].[CogInStr]' function does not exist.

Is there any method to find the registered classes/functions for the Assemblies added in Analysis Service.

Tuesday, March 20, 2012

Churn Rate - two different date dim''s

I am trying to create a calculated measure in my cube (MDX Exprsssion), but first I want to write the query in MDX so I can test it. I am having issues getting this to be "dynamic"

WITH

MEMBER Measures.[Disconnects] AS

(

(

[New Subscription Date].[Calendar Date].[2007-07-15 00:00:00],

[Transaction Time].[Calendar Date].[2007-07-15 00:00:00]

),

[Measures].[Subscription Cancels]

)

MEMBER Measures.[Subscriptions] AS

(

(

[New Subscription Date].[Calendar Date].[2007-07-15 00:00:00],

[Transaction Time].[Calendar Date].[2007-07-15 00:00:00]

),

[Measures].[Subscriptions New]

)

SELECT {

Measures.[Subscriptions]

,[Measures].[Disconnects]

} ON COLUMNS

FROM [MyCube]

this query above gives me the correct values for the day I have in there, but I want it to work over all days, and so the end users can slice by other dim's as well. Basically I am trying to get the number of disconnects that occured on the same day as that disconnect subscribed. I have a feeling my underlying cube/dw is too aggregated already or something else, but I can get this pretty close to what I want. Does anyone have any insight? I have been looking at this

http://sqljunkies.com/WebLog/mosha/archive/2007/06/01/count_in_flight_mdx.aspx

because it is similar, with the two different date dim's, but I just want to always get results where the two date dim's are the same day...

Thanks

If we just take the first measure (as both can use the same pattern) using link member should make the date range dynamic. I needed to pick one of the dates as the one that you will be analyzing by, so I assumed [Transaction Time] was probably the one.

eg.

MEMBER Measures.[Disconnects] AS

(

LinkMember([Transaction Time].[Calendar Date].CurrentMember,

[New Subscription Date].[Calendar Date]

),

[Measures].[Subscription Cancels]

)

This should work OK when you are looking at specific days for Transaction Time, but if you wanted to look at the sum of all transactions where the cancellation and subscription occurred on the same date for a month, week, quarter etc. , assuming that you had a [Calendar] hierarchy then you would need to do something like the following in order to sum over a set of days.

MEMBER Measures.[Disconnects] AS

SUM(

DESCENDANTS([Transaction Time].[Calendar].CurrentMember,

[Transaction Time].[Calendar].[Calendar Date])

,

(

LinkMember([Transaction Time].[Calendar Date].CurrentMember,

[New Subscription Date].[Calendar Date]

),

[Measures].[Subscription Cancels]

)

)

)

|||

wow yeah, ok I thought maybe LinkMember was the route to go.. thing is, I dont know about the Calendar hierarchy, I dont think mine is set up right, what woudl you suggest as a hierarchy?

When i implement the query using link member, and then say, look at one month, and if i put the date ON ROWS, every day in the month has the same values, and the query takes forever to run

I think the solution above is totally the right track though, maybe I just need to tweak something more...

|||

dart_board wrote:

wow yeah, ok I thought maybe LinkMember was the route to go.. thing is, I dont know about the Calendar hierarchy, I dont think mine is set up right, what woudl you suggest as a hierarchy?

When i implement the query using link member, and then say, look at one month, and if i put the date ON ROWS, every day in the month has the same values, and the query takes forever to run

In regards to the hierarchy, I used Calendar as an example as it is something that most people can understand. When I set up a date hierarchy, personally, I usually set up one (or more) hierarchies and then I usually hide the "raw" attributes that are present in the hierarchy. You don't have to do this, you can leave the attributes separate, but the important thing is to get your attribute relationships set up correctly, which it sounds like might be an issue in your case as this would lead to apparent duplicating values.

It's important the each attribute either has a direct or indirect (not both) relationship to the key attribute. And indirect relationship is where one attribute is related to another to form a sort of chain back to the key attribute. One way of thinking of relationships is that an attribute has a relationship to it's parent. So a TimeID has a relationship to a Date and a Date has a relationship to a month and so on. Notice that Year is at the top level of granularity so it is not related to any other attributes.

eg.

TimeID

- Date

Date

- Month

Month

- Quarter

Quarter

- Year

Year

If you don't create explicit hierarchies in your date dimension, or you want to leave the "raw" attributes visible, you should be able to replace the descendants function with the existing keyword which should reduce the set of Date members down to just those that are related to what ever Time attribute is currently selected. (it figures this out using attribute relationships, so these need to be right). Notice that I have used a naming convention of <dimension>.<Attribute>.<level>.members, this is important as if you just used <dimension>.<attribute>.members, it would include the default "All" member and would return all dates which is not what you want.

MEMBER Measures.[Disconnects] AS

SUM(

EXISTING [Transaction Time].[Date].[Date].Members)

,

(

LinkMember([Transaction Time].[Calendar Date].CurrentMember,

[New Subscription Date].[Calendar Date]

),

[Measures].[Subscription Cancels]

)

)

)

Hope this helps

|||yeah that totally makes sense. I brought up a while ago that our hierarchies weren't set up correctly, but no one would beleive me Smile - The EXISTING seems to work well. My only issue now is that when I try to use BOTH caclulated measures together, one is summed up over all and one is correct, depending on which date I slice on (transaction or new subscription) Its like I can get either one or the other to work, but not both together.

I will keep digging into that, if you have any quick insight that would be awesome. You really know your stuff Smile

Thursday, March 8, 2012

Children of the Children in MDX

Hi, all
I'm quite new to MDX.
What I'd like to know is weather it is possible to select all the children of the children of a given node in one-line query. Say we have [Driver].[All Drivers] dimension level. And I want to do something like "[Driver].[All Drivers].Children.Children" instead of obtaining the results with the use of "CrossJoin/Union" . E. g.:

{
Crossjoin({[Driver].[All Drivers].[564654 - Andrew]},
[ActivityPerDriverDailyEvents].[All Events].[Tue - 03/01/2006].Children)), Crossjoin({[Driver].[All Drivers].[564654 - Andrew]},
[ActivityPerDriverDailyEvents].[All Events].[Wed - 04/01/2006].Children)), Crossjoin({[Driver].[All Drivers].[564654 - Andrew]},
[ActivityPerDriverDailyEvents].[All Events].[Thu - 05/01/2006].Children)), Crossjoin({[Driver].[All Drivers].[564654 - Andrew]},
[ActivityPerDriverDailyEvents].[All Events].[Fri - 06/01/2006].Children))
}

Is there any other way of obtaining such a results without hardcoding the dates? Thank you.

Regards,
Roman

Roman,

I believe the function that you are looking for is "Generate".

Generate(<<Set1>>, <<Set2>>[,ALL])

Generate will take the members of the first set supplied to the function and apply them to the second set definition. It is almost like a for each loop in terms of the way it works. In the examples I have below using adventure works, Query 1 will return the US and the half years for 2003. Query 2 will return the US and the children of the half years (quarters) for 2003.

HTH,

- Steve

Query 1:

SELECT { [Measures].[Internet Sales Amount] } ON COLUMNS ,

{{[Customer].[Customer Geography].[Country].&[United States]} *

{[Date].[Calendar].[Calendar Year].&[2003].CHILDREN}} ON ROWS

FROM [Direct Sales]

CELL PROPERTIES VALUE, FORMATTED_VALUE, CELL_ORDINAL, ACTION_TYPE

Query 2:

SELECT { [Measures].[Internet Sales Amount] } ON COLUMNS ,

{{[Customer].[Customer Geography].[Country].&[United States]} *

Generate({[Date].[Calendar].[Calendar Year].&[2003].CHILDREN},

{[Date].[Calendar].CurrentMember.Children})} ON ROWS

FROM [Direct Sales]

CELL PROPERTIES VALUE, FORMATTED_VALUE, CELL_ORDINAL, ACTION_TYPE

|||Hi, Steve
In the dialect of MDX (Mondrian) I'm dealing with it would be impossible to use the Generate() method in such a context. So I used Descendants() method instead. And that piece of MDX code from previous post has turned to:

NonEmptyCrossJoin(
{[Driver].[All Drivers].[564654 - Andrew]},
{Descendants([ActivityPerDriverDailyEvents].[All Events])}
)

Thanks for your help!
Roman