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朋友提供源码,受益匪浅。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。