SQLCLR(二)存储过程和自定义函数
自定义函数和存储过程在.net里其实都是方法。只是方法上方标注[Microsoft.SqlServer.Server.SqlProcedure]
和[Microsoft.SqlServer.Server.SqlFunction]不同而已。自定义函数又分TVF函数和Scalar两种,最大区别在于TVF返回表后者返回Scalar(标量),这一篇我们做一下比较。
先看两段代码
存储过程:
 using System;
using System;
 using System.Data;
using System.Data;
 using System.Data.SqlClient;
using System.Data.SqlClient;
 using System.Data.SqlTypes;
using System.Data.SqlTypes;
 using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Server;


 public partial class StoredProcedures
public partial class StoredProcedures
 {
{
 //这里是告诉sqlserver,这个方法要注册成存储过程
    //这里是告诉sqlserver,这个方法要注册成存储过程
 //我感觉[Attribute]这个东西翻译成标签更形像:)
    //我感觉[Attribute]这个东西翻译成标签更形像:)
 [Microsoft.SqlServer.Server.SqlProcedure]
    [Microsoft.SqlServer.Server.SqlProcedure]
 public static void TestStoredProcedure(string name, ref string outstr)
    public static void TestStoredProcedure(string name, ref string outstr)
 {
    {
 // 在此处放置代码
        // 在此处放置代码
 outstr = "hello," + name;
        outstr = "hello," + name;

 using (SqlConnection cn = new SqlConnection())
        using (SqlConnection cn = new SqlConnection())
 {
        {
 //使用上下文链接也就是当前数据库链接
            //使用上下文链接也就是当前数据库链接
 cn.ConnectionString = "context connection=true";
            cn.ConnectionString = "context connection=true";
 using (SqlCommand cmd = cn.CreateCommand())
            using (SqlCommand cmd = cn.CreateCommand())
 {
            {
 cmd.CommandText = "Select * from userinfo";
                cmd.CommandText = "Select * from userinfo";
 cn.Open();
                cn.Open();
 //SqlContext.Pipe.Send这个方法输出结果集
                //SqlContext.Pipe.Send这个方法输出结果集
 //接受SqlDataReader,SqlDataRecord和string
                //接受SqlDataReader,SqlDataRecord和string
 SqlContext.Pipe.Send(cmd.ExecuteReader());
                SqlContext.Pipe.Send(cmd.ExecuteReader());
 //你也可以用下边这样
                //你也可以用下边这样
 //SqlContext.Pipe.ExecuteAndSend(cmd);
                //SqlContext.Pipe.ExecuteAndSend(cmd);
 }
            }
 }
        }
 }
    }
 };
};
 执行存储过程
执行存储过程
 DECLARE @name nvarchar(4000)
DECLARE @name nvarchar(4000)
 DECLARE @outstr nvarchar(4000)
DECLARE @outstr nvarchar(4000)
 set @name='david fan'
set @name='david fan'
 -- TODO: 在此处设置参数值。
-- TODO: 在此处设置参数值。
 EXECUTE [TestProject].[dbo].[TestStoredProcedure]
EXECUTE [TestProject].[dbo].[TestStoredProcedure] 
 @name
   @name
 ,@outstr OUTPUT
  ,@outstr OUTPUT
 print @outstr
print @outstr
结果如下

输出参数返回值
 
 
自定义函数
一,TVF函数
示例函数的作用是搜索目录下的某一类型的文件
 using System;
using System;
 using System.Data;
using System.Data;
 using System.Data.Sql;
using System.Data.Sql;
 using System.Data.SqlTypes;
using System.Data.SqlTypes;
 using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Server;
 using System.Collections;
using System.Collections;
 using System.IO;
using System.IO;
 using System.Security.Principal;
using System.Security.Principal;

 public partial class UserDefinedFunctions
public partial class UserDefinedFunctions
 {
{
 //需要返回一个表时用TVF(streaming table-valued function)
    //需要返回一个表时用TVF(streaming table-valued function)
 //可以用select from 语句查询这个方法的返回
    //可以用select from 语句查询这个方法的返回
 //TVF需要返回Ienumerable接口,例如:Array,这里返回一个数组
    //TVF需要返回Ienumerable接口,例如:Array,这里返回一个数组

 //FillRowMethodName为填充表行的方法
    //FillRowMethodName为填充表行的方法
 //TableDefinition为表结构,对应FillRowMethodName方法的参数
    //TableDefinition为表结构,对应FillRowMethodName方法的参数
 [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "BuildRow",
    [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "BuildRow",
 TableDefinition = "Name nvarchar(32), Length bigint, Modified DateTime")]
     TableDefinition = "Name nvarchar(32), Length bigint, Modified DateTime")]
 public static IEnumerable FileListCs(string directoryName, string pattern)
    public static IEnumerable FileListCs(string directoryName, string pattern)
 {
    {
 FileInfo[] files;
        FileInfo[] files;
 //模拟当前SQL安全上下文
       //模拟当前SQL安全上下文
 WindowsImpersonationContext OriginalContext= SqlContext.WindowsIdentity.Impersonate();
        WindowsImpersonationContext OriginalContext= SqlContext.WindowsIdentity.Impersonate();
 try
        try
 {
        {
 DirectoryInfo di = new DirectoryInfo(directoryName);
            DirectoryInfo di = new DirectoryInfo(directoryName);
 files = di.GetFiles(pattern);
            files = di.GetFiles(pattern);
 }
        }
 finally
        finally
 {
        {
 if (OriginalContext != null)
            if (OriginalContext != null)
 {
            {
 OriginalContext.Undo();
                OriginalContext.Undo();
 }
            }
 }
        }
 return files;
        return files;
 }
    }

 public static void BuildRow(object Obj,
    public static void BuildRow(object Obj,
 ref SqlString fileName,
          ref SqlString fileName,
 ref SqlInt64 fileLength,
          ref SqlInt64 fileLength,
 ref SqlDateTime fileModified)
          ref SqlDateTime fileModified)
 {
    {
 if (Obj != null)
        if (Obj != null)
 {
        {
 FileInfo file = (FileInfo)Obj;
            FileInfo file = (FileInfo)Obj;
 fileName = file.Name;
            fileName = file.Name;
 fileLength = file.Length;
            fileLength = file.Length;
 fileModified = file.LastWriteTime;
            fileModified = file.LastWriteTime;
 }
        }
 else
        else
 {
        {
 fileName = SqlString.Null;
            fileName = SqlString.Null;
 fileLength = SqlInt64.Null;
            fileLength = SqlInt64.Null;
 fileModified = SqlDateTime.Null;
            fileModified = SqlDateTime.Null;
 }
        }
 }
    }
 }因为这个函数对于sqlserver来讲要访问外部资源,所以需要配置一下项目和sqlserver2005
}因为这个函数对于sqlserver来讲要访问外部资源,所以需要配置一下项目和sqlserver2005
项目右键属性,数据库,权限级别选外部

打开sqlserver2005查询分析器执行下边语句 TestProject 为我的数据库名,你的如果不是,当然需要修改了。
 ALTER DATABASE TestProject SET TRUSTWORTHY ON;成功后,项目右键部署。
ALTER DATABASE TestProject SET TRUSTWORTHY ON;成功后,项目右键部署。
查询分析器中执行
 SELECT * FROM [TestProject].[dbo].[FileListCs] (
SELECT * FROM [TestProject].[dbo].[FileListCs] (
 'c:\'
   'c:\'
 ,'*.txt')结果如下
  ,'*.txt')结果如下

二,Scalar 函数
这类函数返回类型如图,像SqlString这类sqlserver的scalar类型

下面就是这类函数的一个小例子。
 using System;
using System;
 using System.Data;
using System.Data;
 using System.Data.SqlClient;
using System.Data.SqlClient;
 using System.Data.SqlTypes;
using System.Data.SqlTypes;
 using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Server;

 public partial class UserDefinedFunctions
public partial class UserDefinedFunctions
 {
{
 [Microsoft.SqlServer.Server.SqlFunction]
    [Microsoft.SqlServer.Server.SqlFunction]
 public static SqlString ScalarFunction()
    public static SqlString ScalarFunction()
 {
    {
 // 在此处放置代码
        // 在此处放置代码
 return new SqlString("Hello");
        return new SqlString("Hello");
 }
    }
 };sqlserver查询查询分析器中运行如下语句
};sqlserver查询查询分析器中运行如下语句
 SELECT [TestProject].[dbo].[ScalarFunction] ()结果如下
SELECT [TestProject].[dbo].[ScalarFunction] ()结果如下

第二篇完成,谢谢大家指教!
和[Microsoft.SqlServer.Server.SqlFunction]不同而已。自定义函数又分TVF函数和Scalar两种,最大区别在于TVF返回表后者返回Scalar(标量),这一篇我们做一下比较。
先看两段代码
存储过程:
 using System;
using System; using System.Data;
using System.Data; using System.Data.SqlClient;
using System.Data.SqlClient; using System.Data.SqlTypes;
using System.Data.SqlTypes; using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Server;

 public partial class StoredProcedures
public partial class StoredProcedures {
{ //这里是告诉sqlserver,这个方法要注册成存储过程
    //这里是告诉sqlserver,这个方法要注册成存储过程 //我感觉[Attribute]这个东西翻译成标签更形像:)
    //我感觉[Attribute]这个东西翻译成标签更形像:) [Microsoft.SqlServer.Server.SqlProcedure]
    [Microsoft.SqlServer.Server.SqlProcedure] public static void TestStoredProcedure(string name, ref string outstr)
    public static void TestStoredProcedure(string name, ref string outstr) {
    { // 在此处放置代码
        // 在此处放置代码 outstr = "hello," + name;
        outstr = "hello," + name;
 using (SqlConnection cn = new SqlConnection())
        using (SqlConnection cn = new SqlConnection()) {
        { //使用上下文链接也就是当前数据库链接
            //使用上下文链接也就是当前数据库链接 cn.ConnectionString = "context connection=true";
            cn.ConnectionString = "context connection=true"; using (SqlCommand cmd = cn.CreateCommand())
            using (SqlCommand cmd = cn.CreateCommand()) {
            { cmd.CommandText = "Select * from userinfo";
                cmd.CommandText = "Select * from userinfo"; cn.Open();
                cn.Open(); //SqlContext.Pipe.Send这个方法输出结果集
                //SqlContext.Pipe.Send这个方法输出结果集 //接受SqlDataReader,SqlDataRecord和string
                //接受SqlDataReader,SqlDataRecord和string SqlContext.Pipe.Send(cmd.ExecuteReader());
                SqlContext.Pipe.Send(cmd.ExecuteReader()); //你也可以用下边这样
                //你也可以用下边这样 //SqlContext.Pipe.ExecuteAndSend(cmd);
                //SqlContext.Pipe.ExecuteAndSend(cmd); }
            } }
        } }
    } };
};
 DECLARE @name nvarchar(4000)
DECLARE @name nvarchar(4000) DECLARE @outstr nvarchar(4000)
DECLARE @outstr nvarchar(4000) set @name='david fan'
set @name='david fan' -- TODO: 在此处设置参数值。
-- TODO: 在此处设置参数值。 EXECUTE [TestProject].[dbo].[TestStoredProcedure]
EXECUTE [TestProject].[dbo].[TestStoredProcedure]  @name
   @name ,@outstr OUTPUT
  ,@outstr OUTPUT print @outstr
print @outstr结果如下
输出参数返回值
自定义函数
一,TVF函数
示例函数的作用是搜索目录下的某一类型的文件
 using System;
using System; using System.Data;
using System.Data; using System.Data.Sql;
using System.Data.Sql; using System.Data.SqlTypes;
using System.Data.SqlTypes; using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Server; using System.Collections;
using System.Collections; using System.IO;
using System.IO; using System.Security.Principal;
using System.Security.Principal;
 public partial class UserDefinedFunctions
public partial class UserDefinedFunctions {
{ //需要返回一个表时用TVF(streaming table-valued function)
    //需要返回一个表时用TVF(streaming table-valued function) //可以用select from 语句查询这个方法的返回
    //可以用select from 语句查询这个方法的返回 //TVF需要返回Ienumerable接口,例如:Array,这里返回一个数组
    //TVF需要返回Ienumerable接口,例如:Array,这里返回一个数组
 //FillRowMethodName为填充表行的方法
    //FillRowMethodName为填充表行的方法 //TableDefinition为表结构,对应FillRowMethodName方法的参数
    //TableDefinition为表结构,对应FillRowMethodName方法的参数 [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "BuildRow",
    [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "BuildRow", TableDefinition = "Name nvarchar(32), Length bigint, Modified DateTime")]
     TableDefinition = "Name nvarchar(32), Length bigint, Modified DateTime")] public static IEnumerable FileListCs(string directoryName, string pattern)
    public static IEnumerable FileListCs(string directoryName, string pattern) {
    { FileInfo[] files;
        FileInfo[] files; //模拟当前SQL安全上下文
       //模拟当前SQL安全上下文 WindowsImpersonationContext OriginalContext= SqlContext.WindowsIdentity.Impersonate();
        WindowsImpersonationContext OriginalContext= SqlContext.WindowsIdentity.Impersonate(); try
        try {
        { DirectoryInfo di = new DirectoryInfo(directoryName);
            DirectoryInfo di = new DirectoryInfo(directoryName); files = di.GetFiles(pattern);
            files = di.GetFiles(pattern); }
        } finally
        finally {
        { if (OriginalContext != null)
            if (OriginalContext != null) {
            { OriginalContext.Undo();
                OriginalContext.Undo(); }
            } }
        } return files;
        return files; }
    }
 public static void BuildRow(object Obj,
    public static void BuildRow(object Obj, ref SqlString fileName,
          ref SqlString fileName, ref SqlInt64 fileLength,
          ref SqlInt64 fileLength, ref SqlDateTime fileModified)
          ref SqlDateTime fileModified) {
    { if (Obj != null)
        if (Obj != null) {
        { FileInfo file = (FileInfo)Obj;
            FileInfo file = (FileInfo)Obj; fileName = file.Name;
            fileName = file.Name; fileLength = file.Length;
            fileLength = file.Length; fileModified = file.LastWriteTime;
            fileModified = file.LastWriteTime; }
        } else
        else {
        { fileName = SqlString.Null;
            fileName = SqlString.Null; fileLength = SqlInt64.Null;
            fileLength = SqlInt64.Null; fileModified = SqlDateTime.Null;
            fileModified = SqlDateTime.Null; }
        } }
    } }
}项目右键属性,数据库,权限级别选外部
打开sqlserver2005查询分析器执行下边语句 TestProject 为我的数据库名,你的如果不是,当然需要修改了。
 ALTER DATABASE TestProject SET TRUSTWORTHY ON;
ALTER DATABASE TestProject SET TRUSTWORTHY ON;查询分析器中执行
 SELECT * FROM [TestProject].[dbo].[FileListCs] (
SELECT * FROM [TestProject].[dbo].[FileListCs] ( 'c:\'
   'c:\' ,'*.txt')
  ,'*.txt')二,Scalar 函数
这类函数返回类型如图,像SqlString这类sqlserver的scalar类型
下面就是这类函数的一个小例子。
 using System;
using System; using System.Data;
using System.Data; using System.Data.SqlClient;
using System.Data.SqlClient; using System.Data.SqlTypes;
using System.Data.SqlTypes; using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Server;
 public partial class UserDefinedFunctions
public partial class UserDefinedFunctions {
{ [Microsoft.SqlServer.Server.SqlFunction]
    [Microsoft.SqlServer.Server.SqlFunction] public static SqlString ScalarFunction()
    public static SqlString ScalarFunction() {
    { // 在此处放置代码
        // 在此处放置代码 return new SqlString("Hello");
        return new SqlString("Hello"); }
    } };
}; SELECT [TestProject].[dbo].[ScalarFunction] ()
SELECT [TestProject].[dbo].[ScalarFunction] ()第二篇完成,谢谢大家指教!
 
                     
                    
                 
                    
                 


 
     
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号