这几天来,努力学习了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开发--关于TableViewCell的可视化设置细节

    由于时间问题,本篇博文很简略. 1.关于设置Cell的边距问题

  2. 详解 Spotlight on Unix 监控Linux服务器

    1.安装 Spotlight on Unix 下载地址:http://yunpan.cn/QNWyEEvNS4xc9  访问密码 1c7d 傻瓜安装 2.配置spotlight登陆用户,注意spotl ...

  3. 什么是ODBO---OLE DB for OLAP

      我怎么一步一步追到ODBO了?   mondrian核心api->olap4j->jedox也在用olap4j->ODBO? ODBO是什么呢? OLE DB for OLAP ...

  4. Java注解一谈

    阅读目录 1.元注解 2.自定义注解 3.注解处理器 android注解框架解析 我们经常会在java代码里面看到:“@Override”,“@Target”等等样子的东西,这些是什么? 在java里 ...

  5. tar包在linux下 java安装

    总的原则:将jdk-7u10-linux-x64.tar.gz压缩包解压至/usr/lib/jdk,设置jdk环境变量并将其修改为系统默认的jdk 1.将jdk-7u5-linux-x64.tar.g ...

  6. [Linux 性能检测工具]TOP

    TOP NAME 显示linux任务 语法 top -hv | -abcHimMsS -d delay -n iterations -p pid [, pid ...] 描述 top程序提供了系统实时 ...

  7. x01.os.1: BIOS 中断

    这只是一点准备工作.为了显示字符串,需要调用中断:int  0x10 (AH=0x13).具体参数设置,参考我的归纳整理如下: INT 10 (AH = 0) -----------------功能: ...

  8. Android UI编程(1)——九宫格(GridView)

    (转自:http://blog.csdn.net/Thanksgining/article/details/42968847) 参考博客:http://blog.csdn.net/xyz_lmn/ar ...

  9. 地图编辑器V2.3

    MapEditorV2.3 changelog: ====================================== V2.9.0 (2013-11-18)----------------- ...

  10. find 命令

    1.当前目录下查找"test.cpp"文件 find ./ -name test.cpp 2.当前查找含有"abcdef"字符串的文件 find ./ | xa ...