这几天来,努力学习了CLR的存储过程,创建与部署。从普通的存储过程,带参数,以及Output返回值等。

Insus.NET今天学习一个例子,怎样实现CLR Table-Valued函数。在数据库中,我们可以看到很多种函数类型,Table-falued function,Scalar-valued function 等等。

这篇练习的CLR中编写的函数就是table-valued function。

在VS开发SQL的 CLR程序,有简单有复杂,看开发时的衡量了。有些在SQL中无法实现的,可以写成CLR,然后再部署至SQL中。此篇并没有看出两者之间的优势,仅是一个例子作为参考。

比如我们想创建一个多表查询LEFT JOIN。把SQL语句写成一个table-valued函数。这个多表查询,所返回的字段,定义成一个类别:

上面代码示例,可复制代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlTypes;
using System.Text; namespace Insus.NET
{
class Fruit
{
public byte Fruit_nbr { get; set; }
public byte FruitCategory_nbr { get; set; }
public string CategoryName { get; set; }
public byte FruitKind_nbr { get; set; }
public string KindName { get; set; }
public string FruitName { get; set; }
}
}

创建一个新Item:

按下面的步骤,在标记5中选择SQL CLR C# User Defined Function。

标记6,给一个名字,标记7"Add"之后:

删除#14至#19行代码,添加下面代码:

上面代码示例,可复杂代码:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using Insus.NET;
using System.Collections.Generic; public partial class UserDefinedFunctions
{
[SqlFunction(DataAccess = DataAccessKind.Read,
FillRowMethodName = "Item_FillRow",
TableDefinition = "Fruit_nbr TINYINT,FruitCategory_nbr TINYINT, " +
"CategoryName NVARCHAR(30),FruitKind_nbr TINYINT," +
"KindName NVARCHAR(30),FruitName NVARCHAR(30)"
)
]
public static IEnumerable Tvf_Fruit()
{
List<Fruit> fruitConnections = new List<Fruit>();
using (SqlConnection connection = new SqlConnection("context connection=true"))
{
connection.Open();
string sql = "SELECT [Fruit_nbr],[FruitCategory_nbr],[CategoryName]," +
"u_fk.[FruitKind_nbr],[KindName],[FruitName] FROM [dbo].[Fruit] AS f " +
"LEFT JOIN [dbo].[udf_FruitKind]() AS u_fk ON (f.[FruitKind_nbr] = u_fk.[FruitKind_nbr])";
using (SqlCommand command = new SqlCommand(sql, connection))
{
using (SqlDataReader objDr = command.ExecuteReader())
{
while (objDr.Read())
{
Fruit oFruit = new Insus.NET.Fruit();
oFruit.Fruit_nbr = (byte)objDr["Fruit_nbr"];
oFruit.FruitCategory_nbr = (byte)objDr["FruitCategory_nbr"];
oFruit.CategoryName = objDr["CategoryName"].ToString();
oFruit.FruitKind_nbr = (byte)objDr["FruitKind_nbr"];
oFruit.KindName = objDr["KindName"].ToString();
oFruit.FruitName = objDr["FruitName"].ToString();
fruitConnections.Add(oFruit);
}
}
}
}
return fruitConnections;
} private static void Item_FillRow(object source, out SqlByte fruit_nbr,
out SqlByte fruitCategory_nbr, out SqlChars categoryName,
out SqlByte fruitKind_nbr, out SqlChars kindName, out SqlChars fruitName)
{
Fruit fruit = (Fruit)source;
fruit_nbr = new SqlByte(fruit.Fruit_nbr);
fruitCategory_nbr = new SqlByte(fruit.FruitCategory_nbr);
categoryName = new SqlChars(fruit.CategoryName);
fruitKind_nbr = new SqlByte(fruit.FruitKind_nbr);
kindName = new SqlChars(fruit.KindName);
fruitName = new SqlChars(fruit.FruitName);
}
}

接下来,Build,然后可以部署至SQL中去。

上面可复制代码:

IF EXISTS (SELECT * FROM sys.objects WHERE name = 'Tvf_Fruit')
DROP FUNCTION Tvf_Fruit;
GO IF EXISTS (SELECT * FROM sys.assemblies WHERE name = 'FruitClr')
DROP ASSEMBLY FruitClr;
GO CREATE ASSEMBLY FruitClr
FROM 'E:\FruitClr.dll'
WITH PERMISSION_SET = SAFE;
GO CREATE FUNCTION Tvf_Fruit()
RETURNS TABLE (
Fruit_nbr TINYINT,
FruitCategory_nbr TINYINT,
CategoryName NVARCHAR(30),
FruitKind_nbr TINYINT,
KindName NVARCHAR(30),
FruitName NVARCHAR(30)
)
AS
EXTERNAL NAME [FruitClr].UserDefinedFunctions.Tvf_Fruit;
GO

执行成功之后,你肯定会发现SQL发生变化的两个位置:

此时table-valued function创建成功了,在查询分析器执行一下Tvf_Fruit()函数。

下面内容于2015-03-31 09:30分添加:
看看执行的效率如何? 标记1是原始写法,标记2是写成Clr函数。它们得到结果是一样的。

CLR Table-Valued函数的更多相关文章

  1. R中利用apply、tapply、lapply、sapply、mapply、table等函数进行分组统计

    apply函数(对一个数组按行或者按列进行计算): 使用格式为: apply(X, MARGIN, FUN, ...) 其中X为一个数组:MARGIN为一个向量(表示要将函数FUN应用到X的行还是列) ...

  2. 链接脚本(Linker Script)应用实例(一)使用copy table将函数载入到RAM中运行

    将函数载入到RAM中运行需要以下三个步骤: (1)用编译器命令#pragma section "<section name>" <user functions&g ...

  3. LUA table中函数的调用

    1 lua中函数作为表中元素时有三种定义方式 采用‘:’来定义,实际上隐藏了一个形参的声明,这个形参会截获调用函数时的第一个实参并把它赋值给self 2 调用方式,点号和冒号 functb:hello ...

  4. vue的iview列表table render函数设置DOM属性值的方法

    { title: '负责人社保照片', key: 'leaderIdNumber', render: (h, params) => { return h('img',{domProps:{ sr ...

  5. 转载——CLR标量函数、表值函数和聚合函数(UDA)

    本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...

  6. SQL Server CLR 使用 C# 自定义函数

    一.简介 Microsoft SQL Server 2005之后,实现了对 Microsoft .NET Framework 的公共语言运行时(CLR)的集成.CLR 集成使得现在可以使用 .NET ...

  7. PCB MS SQL 标量函数(CLR) 实现DataTable转HTML的方法

    一.准备需转为HMLT字符串的DataTable数据 在数据库中执行一段SQL返回的数据 需转换后的HTML的文本 <html ><head></head>< ...

  8. PCB MS SQL 标量函数(CLR) 实现DataTable转Json方法

    一.准备需转为json字符串的DataTable数据 在数据库中执行一段SQL返回的数据 需转换后的JSON字符串的效果 [{"TechName":"开料",& ...

  9. PCB MS SQL表值函数与CLR 表值函数 (例:字符串分割转表)

    将字符串分割为表表经常用到,这里 SQL表值函数与CLR  表值函数,两种实现方法例出来如下: SELECT * FROM FP_EMSDB_PUB.dbo.SqlSplit('/','1oz/1.5 ...

  10. R read.table函数的check.names参数

    今天用cummeRbund 对cuffdiff的结果进行可视化, 一直报错,之前跑的好好的,找了半天原因, 原来出现在read.table这个函数上: read.table有一个参数check.nam ...

随机推荐

  1. 【代码笔记】iOS-改变导航条标题的颜色为红色

    一,效果图. 二,代码. RootViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional se ...

  2. C++语言-05-三大特性

    概述 C++ 是面向对象的语言,具备 OOP 的基本特性. 封装 概念 将数据和操作数据的函数绑定在一起 作用 避免受到外界的干扰和误用,确保了安全 与封装相关的概念 数据抽象 仅向用户暴露接口而把具 ...

  3. IrfanView 4.36 中文版发布了

    IrfanView 4.36 简体中文便携版 小而快的图片浏览器 仅仅不到2M的小软件,功能却能与体积大到几十M的ACDSee相媲美!这个软件就是IrfanView.图片.音频.视频浏览,图片批量格式 ...

  4. Sql Server之旅——第十站 看看DML操作对索引的影响

    我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 ...

  5. R语言数据的输入

    键盘输入 调用edit函数,比如我们要让用户输入一个长度为5的向量并赋值给变量a,那么可以: a<-vector() a<-edit(a) 另外也可以用函数fix来直接编辑变量,而不需要再 ...

  6. IntelliJ IDEA Cannot find declaration to go to

    最近在用IntelliJ IDEA开发一个微服务的项目的时候,从git clone了代码, 再用IntelliJ IDEA导入项目以后.项目里好多方法,类和属性都无法转到定义或者声明处,无论是Ctrl ...

  7. ASP.NET Core 1.0 安装并发布到Centos 7.2 使用jexus 5.8.2

    安装运行环境 sudoyuminstall libunwind libicu 下载.net core https://www.microsoft.com/net/download 下载完后上传文件 安 ...

  8. android PopupWindow使用实例

    注:点空白或菜单外隐藏popupwindow菜单: 但是,若点击有点击事件的组件则要再写代码手动隐藏: @Override public boolean onTouchEvent(MotionEven ...

  9. android Timer使用方法

    Timer属性:http://www.apihome.cn/api/java/Timer.html 声明创建: private Timer mTimer; protected void onCreat ...

  10. 3.10.17 procfs示例

    /* *    wesley *    the linux module sample of procfs *     *    wesley for testing *    2013-12-23 ...