SQLCLR(二)存储过程和自定义函数

自定义函数和存储过程在.net里其实都是方法。只是方法上方标注[Microsoft.SqlServer.Server.SqlProcedure]
和[Microsoft.SqlServer.Server.SqlFunction]不同而已。自定义函数又分TVF函数和Scalar两种,最大区别在于TVF返回表后者返回Scalar(标量),这一篇我们做一下比较。
先看两段代码
存储过程:
None.gif using  System;
None.gif
using  System.Data;
None.gif
using  System.Data.SqlClient;
None.gif
using  System.Data.SqlTypes;
None.gif
using  Microsoft.SqlServer.Server;
None.gif
None.gif
None.gif
public  partial  class  StoredProcedures
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
//这里是告诉sqlserver,这个方法要注册成存储过程
InBlock.gif    
//我感觉[Attribute]这个东西翻译成标签更形像:)
InBlock.gif
    [Microsoft.SqlServer.Server.SqlProcedure]
InBlock.gif    
public static void TestStoredProcedure(string name, ref string outstr)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 在此处放置代码
InBlock.gif
        outstr = "hello," + name;
InBlock.gif
InBlock.gif        
using (SqlConnection cn = new SqlConnection())
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//使用上下文链接也就是当前数据库链接
InBlock.gif
            cn.ConnectionString = "context connection=true";
InBlock.gif            
using (SqlCommand cmd = cn.CreateCommand())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                cmd.CommandText 
= "Select * from userinfo";
InBlock.gif                cn.Open();
InBlock.gif                
//SqlContext.Pipe.Send这个方法输出结果集
InBlock.gif                
//接受SqlDataReader,SqlDataRecord和string
InBlock.gif
                SqlContext.Pipe.Send(cmd.ExecuteReader());
InBlock.gif                
//你也可以用下边这样
InBlock.gif                
//SqlContext.Pipe.ExecuteAndSend(cmd);
ExpandedSubBlockEnd.gif
            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
;
None.gif
执行存储过程
None.gif DECLARE   @name   nvarchar ( 4000 )
None.gif
DECLARE   @outstr   nvarchar ( 4000 )
None.gif
set   @name = ' david fan '
None.gif
--  TODO: 在此处设置参数值。
None.gif
EXECUTE   [ TestProject ] . [ dbo ] . [ TestStoredProcedure ]  
None.gif   
@name
None.gif  ,
@outstr  OUTPUT
None.gif
print   @outstr

结果如下
b6.JPG
输出参数返回值
b7.JPG 
自定义函数
一,TVF函数
示例函数的作用是搜索目录下的某一类型的文件
None.gif using  System;
None.gif
using  System.Data;
None.gif
using  System.Data.Sql;
None.gif
using  System.Data.SqlTypes;
None.gif
using  Microsoft.SqlServer.Server;
None.gif
using  System.Collections;
None.gif
using  System.IO;
None.gif
using  System.Security.Principal;
None.gif
None.gif
public  partial  class  UserDefinedFunctions
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
//需要返回一个表时用TVF(streaming table-valued function)
InBlock.gif    
//可以用select from 语句查询这个方法的返回
InBlock.gif    
//TVF需要返回Ienumerable接口,例如:Array,这里返回一个数组
InBlock.gif
InBlock.gif    
//FillRowMethodName为填充表行的方法
InBlock.gif    
//TableDefinition为表结构,对应FillRowMethodName方法的参数
InBlock.gif
    [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "BuildRow",
InBlock.gif     TableDefinition 
= "Name nvarchar(32), Length bigint, Modified DateTime")]
InBlock.gif    
public static IEnumerable FileListCs(string directoryName, string pattern)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        FileInfo[] files;
InBlock.gif       //模拟当前SQL安全上下文
InBlock.gif        WindowsImpersonationContext OriginalContext= SqlContext.WindowsIdentity.Impersonate();

InBlock.gif
        try
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            DirectoryInfo di 
= new DirectoryInfo(directoryName);
InBlock.gif            files 
= di.GetFiles(pattern);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (OriginalContext != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                OriginalContext.Undo();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
return files;
ExpandedSubBlockEnd.gif    }

InBlock.gif

InBlock.gif
    public static void BuildRow(object Obj,
InBlock.gif          
ref SqlString fileName,
InBlock.gif          
ref SqlInt64 fileLength,
InBlock.gif          
ref SqlDateTime fileModified)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (Obj != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            FileInfo file 
= (FileInfo)Obj;
InBlock.gif            fileName 
= file.Name;
InBlock.gif            fileLength 
= file.Length;
InBlock.gif            fileModified 
= file.LastWriteTime;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            fileName 
= SqlString.Null;
InBlock.gif            fileLength 
= SqlInt64.Null;
InBlock.gif            fileModified 
= SqlDateTime.Null;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
因为这个函数对于sqlserver来讲要访问外部资源,所以需要配置一下项目和sqlserver2005
项目右键 属性数据库,权限级别外部
b8.JPG
打开sqlserver2005查询分析器执行下边语句 TestProject 为我的数据库名,你的如果不是,当然需要修改了。
None.gif ALTER   DATABASE  TestProject  SET  TRUSTWORTHY  ON ;
成功后,项目右键 部署

查询分析器中执行
None.gif SELECT   *   FROM   [ TestProject ] . [ dbo ] . [ FileListCs ]  (
None.gif   
' c:\ '
None.gif  ,
' *.txt ' )
结果如下
b9.JPG
二,Scalar 函数
这类函数返回类型如图,像SqlString这类sqlserver的scalar类型
b10.JPG
下面就是这类函数的一个小例子。
None.gif using  System;
None.gif
using  System.Data;
None.gif
using  System.Data.SqlClient;
None.gif
using  System.Data.SqlTypes;
None.gif
using  Microsoft.SqlServer.Server;
None.gif
None.gif
public  partial  class  UserDefinedFunctions
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    [Microsoft.SqlServer.Server.SqlFunction]
InBlock.gif    
public static SqlString ScalarFunction()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 在此处放置代码
InBlock.gif
        return new SqlString("Hello");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
;
sqlserver查询查询分析器中运行如下语句
None.gif SELECT   [ TestProject ] . [ dbo ] . [ ScalarFunction ]  ()
结果如下
b11.JPG
第二篇完成,谢谢大家指教!

转载于:https://www.cnblogs.com/DavidFan/archive/2007/05/09/738827.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值