SQL2005CLR函数扩展-深入环比计算的详解
前端之家收集整理的这篇文章主要介绍了
SQL2005CLR函数扩展-深入环比计算的详解,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_502_0@此类问题还可以延伸到类似进销存的批次计算中,这也要关注其他历史记录来决定当前某条记录的状态。sql语句无法简单实现mdx语句的类似功能,必须得用交叉表关联来对比。这里我们用CLR函数来实现mdx语句的类似语法。在select的时候把得到过的做个缓存就可以了。效率应该可以提高不少。clr的代码如下,编译为TestFun.dll,复制到sql服务器的文件目录下。
--------------------------------------------------------------------------------
<div class="codetitle"><a style="CURSOR: pointer" data="35136" class="copybut" id="copybut35136" onclick="doCopy('code35136')"> 代码如下:
<div class="codebody" id="code35136">
using System;
using System.Data;
using System.Data.
sqlClient;
using System.Data.
sqlTypes;
using Microsoft.
sqlServer.Server; public partial class UserDefinedFunctions
{ // 保存当前组当前值
private static System.Collections.Generic.Dictionary <string,SqlString > _listValue = new System.Collections.Generic.Dictionary <string,SqlString >();
// 保存当前组
private static System.Collections.Generic.Dictionary <string,string > _listGroup = new System.Collections.Generic.Dictionary <string,string >(); ///
/// 获取当前组上条记录数值
/// /// <param name="key"> 并发键
/// <param name="currentGroup"> 当前组
/// <param name="currentValue"> 当前组当前值
///
[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]; // 组变更
if (_listGroup[key.Value] != currentGroup.Value)
{
prevMemberValue =
sqlString .Null;
_listGroup[key.Value] = currentGroup.Value;
}
// 值变更
_listValue[key.Value] = currentValue; return prevMemberValue;
}
catch
{
return
sqlString .Null;
}
}
///
/// 初始化并发键
/// /// <param name="key">
///
[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 ;
}
}
///
/// 释放并发键
/// /// <param name="key">
///
[Microsoft.
sqlServer.Server.
sqlFunction ]
public static
sqlBoolean DisposeKey(
sqlString key)
{
try
{
_listValue.Remove(key.Value);
_listGroup.Remove(key.Value);
return true ;
}
catch
{
return false ;
}
}
};
--------------------------------------------------------------------------------
部署和
生成自定义函数,其中考虑到并发,我们还是需要一个并发键来表达当前
查询 --------------------------------------------------------------------------------
<div class="codetitle">
<a style="CURSOR: pointer" data="26850" class="copybut" id="copybut26850" onclick="doCopy('code26850')"> 代码如下:
<div class="codebody" id="code26850">
CREATE ASSEMBLY TestFor
sqlCLR 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 TestFor
sqlCLR. [UserDefinedFunctions]. GetPrevMemberValue
go
CREATE FUNCTION dbo. xfn_initKey
(
@key nvarchar ( 255)
)
RETURNS bit
AS EXTERNAL NAME TestFor
sqlCLR. [UserDefinedFunctions]. InitKey
go
CREATE FUNCTION dbo. xfn_disposeKey
(
@key nvarchar ( 255)
)
RETURNS bit
AS EXTERNAL NAME TestFor
sqlCLR. [UserDefinedFunctions]. DisposeKey
--------------------------------------------------------------------------------
这样我们就可以使用了,测试脚本如下, xfn_GetPrevMemberValue就是
获取上月价格的
函数。
--------------------------------------------------------------------------------
-- 建立测试环境
<div class="codetitle">
<a style="CURSOR: pointer" data="4823" class="copybut" id="copybut4823" onclick="doCopy('code4823')"> 代码如下:
<div class="codebody" id="code4823">
declare @t table (
[ 区域 ]
varchar COLLATE Chinese_PRC_CI_AS NULL,
[TradeMonth]
varchar COLLATE Chinese_PRC_CI_AS NULL,
[TradeMoney] [float] NULL,
[TradeArea] [float] NULL,
[TradePrice] [float] NULL
)
insert into @t
select ' 闵行 ','2007-03','2125714.91','241.65','8796.67' union
select ' 闵行 ','2007-04','8408307.64','907.32','9267.19' union
select ' 闵行 ','2007-05','10230321.95','1095.88','9335.26' union
select ' 浦东 ','2007-01','12738432.25','1419.05','8976.73' union
select ' 浦东 ','2007-02','4970536.74','395.49','12568.05' union
select ' 浦东 ','5985405.76','745.94','8023.98' union
select ' 浦东 ','21030788.61','1146.89','18337.23' union
select ' 普陀 ','1863896','161.39','11549.02' union
select ' 普陀 ','1614015','119.59','13496.24' union
select ' 普陀 ','1059235.19','135.21','7834'