sql2005clr function Extension-detailed analysis of the deep chain calculation

Source: Internet
Author: User
Tags null null
The chain is the month and last month's difference in the proportion of the last month's value. In the complex OLAP computation we often use the concept of the Year-on-year chain, the requirements of the last dimension of a field of the implementation statement is very concise, such as SSAS MDX statements like [dimensions]. Currentmember.prevmember on it,

.

Such issues can also be extended to invoicing-like batch calculations, which also focus on other historical records to determine the status of a current record.

SQL statements cannot easily implement similar functions of an MDX statement, and must be contrasted with a crosstab association. Here we use CLR functions to implement similar syntax for MDX statements. It's OK to make a cache of what you've got when you select it. Efficiency should be improved a lot.

The code for the CLR is compiled as TestFun.dll and copied to the SQL Server's file directory.
--------------------------------------------------------------------------------

Copy Code code as follows:


using System;


using System.Data;


using System.Data.SqlClient;


using System.Data.SqlTypes;


using Microsoft.SqlServer.Server;





public partial class Userdefinedfunctions


{





//Save current group Current value


private static System.Collections.Generic.Dictionary <string, SqlString > _listvalue = new System.Collections . Generic.dictionary <string, SqlString > ();


Save the current group


private static System.Collections.Generic.Dictionary <string, string > _listgroup = new System.Collections.Ge Neric. Dictionary <string, String > ();





///<summary>


///Gets the value of the current group record


///</summary>


///<param name= "key" > Concurrency key </param>


///<param name= "CurrentGroup" > Current group </param>


///<param name= "CurrentValue" > Current group Current value </param>


///<returns></returns>


[Microsoft.SqlServer.Server.SqlFunction]


public static SqlString Getprevmembervalue (SqlString key,sqlstring currentgroup,sqlstring currentValue)


{


if (key). IsNull | | Currentgroup.isnull) return SqlString. Null;








Try


{


SqlString prevmembervalue = _listvalue[key. Value];





//Group Change


if (_listgroup[key. Value]!= currentgroup.value)


{


Prevmembervalue = SqlString. Null;


_listgroup[key. Value] = Currentgroup.value;


}


//value change


_listvalue[key. Value] = CurrentValue;





return prevmembervalue;


}


Catch


{


return SqlString. Null;


}


}


///<summary>


///initializes the concurrency key


///</summary>


///<param name= "key" ></param>


///<returns></returns>


[Microsoft.SqlServer.Server.SqlFunction]


public static SqlBoolean Initkey (SqlString key)


{


Try


{


_listvalue.add (key. Value, SqlString. Null);


_listgroup.add (key. Value, String. Empty);


return true;


}


Catch


{


return false;


}


}


///<summary>


///releases the concurrency key


///</summary>


///<param name= "key" ></param>


///<returns></returns>


[Microsoft.SqlServer.Server.SqlFunction]


public static SqlBoolean Disposekey (SqlString key)


{


Try


{


_listvalue.remove (key. Value);


_listgroup.remove (key. Value);


return true;


}


Catch


{


return false;


}


}


};


--------------------------------------------------------------------------------
Deployment and generation of custom functions, which take into account concurrency, we still need a concurrency key to express the current query
--------------------------------------------------------------------------------

Copy Code code as follows:


CREATE ASSEMBLY testforsqlclr from ' e:/sqlclrdata/testfun.dll ' with permission_set = UnSAFE;


--


Go


CREATE FUNCTION dbo. Xfn_getprevmembervalue


(


@key nvarchar (255),


@initByDim nvarchar (255),


@currentValue nvarchar (255)


)


RETURNS nvarchar (255)


as EXTERNAL NAME testforsqlclr. [Userdefinedfunctions]. Getprevmembervalue


Go


CREATE FUNCTION dbo. Xfn_initkey


(


@key nvarchar (255)


)


RETURNS bit


As EXTERNAL NAME testforsqlclr. [Userdefinedfunctions]. Initkey


Go


CREATE FUNCTION dbo. Xfn_disposekey


(


@key nvarchar (255)


)


RETURNS bit


as EXTERNAL NAME testforsqlclr. [Userdefinedfunctions]. Disposekey


--------------------------------------------------------------------------------
So we can use the test script as follows, Xfn_getprevmembervalue is the function that gets the price last month.
--------------------------------------------------------------------------------
--Establish a test environment

Copy Code code as follows:


declare @t table (


[Area] [varchar] (4) COLLATE chinese_prc_ci_as NULL,


[Trademonth] [varchar] (7) COLLATE chinese_prc_ci_as NULL,


[Trademoney] [float] NULL,


[Tradearea] [float] NULL,


[Tradeprice] [float] NULL


)


INSERT INTO @t


Select ' Minhang ', ' 2007-03 ', ' 2125714.91 ', ' 241.65 ', ' 8796.67 ' union


select ' Minhang ', ' 2007-04 ', ' 8408307.64 ', ' 907.32 ', ' 9267.19 ' union


select ' Minhang ', ' 2007-05 ', ' 10230321.95 ', ' 1095.88 ', ' 9335.26 ' union


Select ' Pudong ', ' 2007-01 ', ' 12738432.25 ', ' 1419.05 ', ' 8976.73 ' union


Select ' Pudong ', ' 2007-02 ', ' 4970536.74 ', ' 395.49 ', ' 12568.05 ' union


Select ' Pudong ', ' 2007-03 ', ' 5985405.76 ', ' 745.94 ', ' 8023.98 ' union


Select ' Pudong ', ' 2007-04 ', ' 21030788.61 ', ' 1146.89 ', ' 18337.23 ' union


select ' Putuo ', ' 2007-01 ', ' 1863896 ', ' 161.39 ', ' 11549.02 ' union


select ' Putuo ', ' 2007-02 ', ' 1614015 ', ' 119.59 ', ' 13496.24 ' union


select ' Putuo ', ' 2007-03 ', ' 1059235.19 ', ' 135.21 ', ' 7834 '


--Test statement

Copy Code code as follows:


declare @key varchar (40)


declare @b bit





Set @key = NEWID ()


Select @b= dbo. Xfn_initkey (@key)





Select area, Trademonth, Tradeprice, Lastmonthprice,


Cast (Round (tradeprice-lastmonthprice) * 100/lastmonthprice, 2) as varchar) + '% ' as chain from (


SELECT *, CAST (dbo. Xfn_getprevmembervalue (@key, Region, Tradeprice) as float) as Lastmonthprice from @t


) T


Select @b= dbo. Xfn_disposekey (@key)


--Results
/*
Area trademonth tradeprice lastmonthprice chain
-------------------------------------------- -------------------------
Minhang 2007-03 8796.67 null null
Minhang 2007-04 9267.19 8796.67 5.35%
Minhang 2007-05 9335.26 9267.19 0.73%
Pudong 2007-01 8976.73 null
Pudong 2007-02 12568.05 8976.73-40.01%
Pudong 2007-03 8023.98 12568-36 16%
2007-04 18337.23 8023.98 128.53%
Putuo 2007-01 11549.02 null null
Putuo 2007-02 13496.24 11549 16.86%
Putuo 2007-03 7834 13496.2-41.95%
*/
------------------------------------------------------------------------ --------
This function is still relatively coarse, and if further refinement can be used to define how to obtain the method of the previous dimension. This is only cached in terms of query order. Interested friends can be perfected.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.