您的位置:首页 > 数据库

SQL Server 2005中开发通用的自定义函数,实现类似Min或MAX函数功能(附源码)

2009-03-15 10:41 766 查看
SQL Server 2005中通用的自定义函数,实现类似Min或MAX函数功能
开发一个通用的自定义函数,适用每个表,而不是某一个具体的表专用,类似SQL Server 2005的Min或MAX函数功能。

源码下载

主要实现:
1、在sql语句中直接可以取出值来。从select 的from 子句中传递表名,参数中传递要判断的字段名,即类似于select max(myid) from mytable 。这样处理就不用对每一个表都写一个函数(里面直接封装表的名称)。
2、因为我想做一个通用的ID流水号生成器,而不是专用于某一个表而实现。所以我想到了max和min这两个东东。通常使用 insert into 来追加记录。想通过以下这种方式追加记录: Insert into mytable (id,other_cols) select getnextid(id),'值' from mytable 。

注意:由于存储过程必须执行一行命令,所以不能满足要求。

源程序:

using System;
using System.Text;
using System.Data;
using System.Data.SqlTypes;
using Microsoft.SqlServer;
using Microsoft.SqlServer.Server;

namespace TestFunction
{
[Serializable()]
[SqlUserDefinedAggregate(Format.UserDefined,
IsInvariantToNulls=true,
IsNullIfEmpty=true,
MaxByteSize=8000
)
]
public class CLRMax:IBinarySerialize
{
string currentValue = string.Empty;

public void Read(System.IO.BinaryReader r)
{
currentValue = r.ReadString();
}

public void Write(System.IO.BinaryWriter w)
{
w.Write(currentValue);
}
//Nothing to do
public void Init()
{

}
public void Accumulate(SqlString value)
{
if (value.IsNull)
return;
if (value.Value.CompareTo(currentValue)>0)
currentValue = value.Value;
}
public void Merge(CLRMax other)
{
if (this.currentValue.CompareTo(other.currentValue) > 0)
this.currentValue = other.currentValue;
}
public SqlString Terminate()
{
return new SqlString(currentValue);
}
}
}


编译成Dll後,就可以在sql中使用了。ex:
编译成CLRMax.dll,放至c:/中。
然後在sql中执行下述语句创建aggregate的function

CREATE ASSEMBLY ClrMax FROM 'C:/ClrMax.dll'
GO
CREATE AGGREGATE ClrMax(@Input NVARCHAR(200)) RETURNS NVARCHAR(MAX)
EXTERNAL NAME [ClrMax].[TestFunction.CLRMax]
GO


开启CLR ENABLED.
exec sp_configure 'show advanced options', '1';
go
reconfigure;
go
exec sp_configure 'clr enabled', '1'
go
reconfigure;
exec sp_configure 'show advanced options', '1';
go


--使用测试.

CREATE TABLE ta (a int,b varchar(10))
GO
CREATE TABLE tb (col1 nvarchar(10),col2 decimal(13,4),col3 datetime,col4 bit)
GO
INSERT INTO ta
SELECT 1,'aa'
UNION ALL
SELECT 2,'aa'
UNION ALL
SELECT 3,'aa'
UNION ALL
SELECT 4,'aa'
UNION ALL
SELECT 10,'bbbbb'
UNION ALL
SELECT 10,'BBBBB'
UNION ALL
SELECT 15,'bbbbZ'

INSERT INTO tb
SELECT 'a',28.4,GETDATE(),0
UNION ALL
SELECT 'b',29.4,GETDATE(),NULL
UNION ALL
SELECT 'c',30.4,DATEADD(DAY,10,GETDATE()),0
GO

SELECT  b, dbo.ClrMax(a) FROM ta GROUP BY b
/*
aa    4
bbbbb    10
bbbbZ    15
*/

SELECT dbo.ClrMax(col1),
dbo.ClrMax(col2),
dbo.ClrMax(col3),
dbo.ClrMax(col4)
FROM    tb
/*
c    30.4000    03 20 2009  9:41PM    0
*/


感谢CSDN的Garnett_KG朋友提供源码,受益匪浅。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: