假如这个世界上只剩下你一个人,当你正坐在屋子里的时候,这时突然响起了敲门声...
用Clr实现的sql表值函数splitIDs
查看( 23 ) /
评论( 0 )
在我们需要批量删除数据,或者批量修改实体的状态时,为了性能我们会直接写一个存储过程,并将这一批数据的id用“,”分隔传递给一个存储过程,然后在存储过程中拆分这个字符串,然后执行删除或者更新状态操作。以前每次执行这种操作时我都会在存储过程中拆分字符串。现在sql server支持用.net clr的程序集写函数,存储过程等等。
]o6o#E*P8tH0 ITPUB个人空间{zF0p;f'mF&y
现在我们就牛刀小试,做一个clr的sql表值函数。该函数的功能就是传入一个用逗号分隔的数字id字符,返回一个只有一列id的表。
o F_3w*`#Z?s/B0 第一步:我们需要新建一个类库项目,并添加一个类SplitIDs
+lo2H5\_q%~%[`,P0 using System;
_Yt"^C`cZ8J0 using System.Collections.Generic;
nw7EHdY0 using System.Text;ITPUB个人空间t#G(t%s)X3re~W
using Microsoft.SqlServer.Server;
2XV(M7p;` JVb#tk0 using System.Collections;ITPUB个人空间z6a k&]l$y2E"t
using System.Data.SqlTypes;
zg qC Hy2CX0
S?*T"f%]0[$W~4lw0 public class SplitIDsITPUB个人空间@qw&Xp1Pc
{ITPUB个人空间 Or3O4Xp,rHu
[SqlFunction(FillRowMethodName = "FillRow")]
6R$r|]'{q"P0 public static IEnumerable DoSplit(String strIDs)ITPUB个人空间W iy-jj:WlS0U
{ITPUB个人空间aK,ge!Y.m V
return strIDs.Split(',');
Y.Gzt&e2SeS0 }ITPUB个人空间.R},@.\(S+u;l;H\
p+bD3{6a,r0 public static void FillRow(Object obj, out SqlInt64 id)ITPUB个人空间!I7KH#vtm!v&w
{ITPUB个人空间/}/v4t~)X-I)m
long value = 0;ITPUB个人空间D*g2L5jkPf7jX-n
long.TryParse((string)obj, out value);
^w2M S0S4c%_Dq8J\p0 id = new SqlInt64(value);ITPUB个人空间\LXb2l.Do3wW
}
E^7`3?.\0c,@ js/t'T0 }ITPUB个人空间"tT&s,W@zA
3h+D)l-fA'[2Rn0 有2个注意的点ITPUB个人空间Xzm"b-c!e
1. 命名空间声明要去掉,我在测试的过程中刚开始有命名空间的声明,总是注册不成功,后来去掉了存储过程的声明,才注册上ITPUB个人空间$rH{E'Png#Q[
2. 方法必须是静态的并且要有SqlFunction特性,表值函数的返回值是IEnurableITPUB个人空间'a8b-y2]x
ITPUB个人空间;g-W^2a j6XfSz DK
第二步:注册程序集到sql server中ITPUB个人空间3q3M;ne]zz$X\4{
USE [DB_Name]ITPUB个人空间MC5T9EX5X7m!l
GOITPUB个人空间V.|Q8H4t?
if (object_id('SplitIDs') is not null)
6zi su(L$esME0 drop function splitIds;ITPUB个人空间j0aF7ote9I+LW;b
GO
*P.CE/S-?@|0 IF EXISTS (SELECT * FROM sys.assemblies asms WHERE asms.name = N'SqlServerUtility')
3EN\9m(]3S nik3B0 DROP ASSEMBLY [SqlServerUtility]
"fK0[[m&dF.H0 go
(Zqb!BY0 CREATE ASSEMBLY SqlServerUtility ITPUB个人空间vx'z{bl4AMc*}'g
FROM 'D:Program FilesMicrosoft SQL Server90UserDefinedAssemblySqlServerUtility.dll' ITPUB个人空间s e7B;|1m!_~6Cd3P
WITH PERMISSION_SET = SAFEITPUB个人空间@l t B\s
GO
Gd)?]C0k0 CREATE FUNCTION SplitIDs(@ids Nvarchar(max))ITPUB个人空间{ @ep3z3k
RETURNS TABLE (id bigint)ITPUB个人空间tS2G\!Ax#fQ
AS
[ wL~-k0 EXTERNAL NAME SqlServerUtility.SplitIDs.DoSplit
:o]6s.o|#GByss0 GOITPUB个人空间XR gSc8?2jc}7i1K
EXEC sp_configure "clr enabled",1 ITPUB个人空间6^&O
]o6o#E*P8tH0 ITPUB个人空间{zF0p;f'mF&y
现在我们就牛刀小试,做一个clr的sql表值函数。该函数的功能就是传入一个用逗号分隔的数字id字符,返回一个只有一列id的表。
o F_3w*`#Z?s/B0 第一步:我们需要新建一个类库项目,并添加一个类SplitIDs
+lo2H5\_q%~%[`,P0 using System;
_Yt"^C`cZ8J0 using System.Collections.Generic;
nw7EHdY0 using System.Text;ITPUB个人空间t#G(t%s)X3re~W
using Microsoft.SqlServer.Server;
2XV(M7p;` JVb#tk0 using System.Collections;ITPUB个人空间z6a k&]l$y2E"t
using System.Data.SqlTypes;
zg qC Hy2CX0
S?*T"f%]0[$W~4lw0 public class SplitIDsITPUB个人空间@qw&Xp1Pc
{ITPUB个人空间 Or3O4Xp,rHu
[SqlFunction(FillRowMethodName = "FillRow")]
6R$r|]'{q"P0 public static IEnumerable DoSplit(String strIDs)ITPUB个人空间W iy-jj:WlS0U
{ITPUB个人空间aK,ge!Y.m V
return strIDs.Split(',');
Y.Gzt&e2SeS0 }ITPUB个人空间.R},@.\(S+u;l;H\
p+bD3{6a,r0 public static void FillRow(Object obj, out SqlInt64 id)ITPUB个人空间!I7KH#vtm!v&w
{ITPUB个人空间/}/v4t~)X-I)m
long value = 0;ITPUB个人空间D*g2L5jkPf7jX-n
long.TryParse((string)obj, out value);
^w2M S0S4c%_Dq8J\p0 id = new SqlInt64(value);ITPUB个人空间\LXb2l.Do3wW
}
E^7`3?.\0c,@ js/t'T0 }ITPUB个人空间"tT&s,W@zA
3h+D)l-fA'[2Rn0 有2个注意的点ITPUB个人空间Xzm"b-c!e
1. 命名空间声明要去掉,我在测试的过程中刚开始有命名空间的声明,总是注册不成功,后来去掉了存储过程的声明,才注册上ITPUB个人空间$rH{E'Png#Q[
2. 方法必须是静态的并且要有SqlFunction特性,表值函数的返回值是IEnurableITPUB个人空间'a8b-y2]x
ITPUB个人空间;g-W^2a j6XfSz DK
第二步:注册程序集到sql server中ITPUB个人空间3q3M;ne]zz$X\4{
USE [DB_Name]ITPUB个人空间MC5T9EX5X7m!l
GOITPUB个人空间V.|Q8H4t?
if (object_id('SplitIDs') is not null)
6zi su(L$esME0 drop function splitIds;ITPUB个人空间j0aF7ote9I+LW;b
GO
*P.CE/S-?@|0 IF EXISTS (SELECT * FROM sys.assemblies asms WHERE asms.name = N'SqlServerUtility')
3EN\9m(]3S nik3B0 DROP ASSEMBLY [SqlServerUtility]
"fK0[[m&dF.H0 go
(Zqb!BY0 CREATE ASSEMBLY SqlServerUtility ITPUB个人空间vx'z{bl4AMc*}'g
FROM 'D:Program FilesMicrosoft SQL Server90UserDefinedAssemblySqlServerUtility.dll' ITPUB个人空间s e7B;|1m!_~6Cd3P
WITH PERMISSION_SET = SAFEITPUB个人空间@l t B\s
GO
Gd)?]C0k0 CREATE FUNCTION SplitIDs(@ids Nvarchar(max))ITPUB个人空间{ @ep3z3k
RETURNS TABLE (id bigint)ITPUB个人空间tS2G\!Ax#fQ
AS
[ wL~-k0 EXTERNAL NAME SqlServerUtility.SplitIDs.DoSplit
:o]6s.o|#GByss0 GOITPUB个人空间XR gSc8?2jc}7i1K
EXEC sp_configure "clr enabled",1 ITPUB个人空间6^&O