起源

    最近项目开发上使用的SQLserver数据库是2008版本,由于08版本的数据是没有字符串合并(STRING_AGG)这个函数(2017版本及以上支持)的,只有用stuff +for xml path('') 来达到效果。所以才有萌生出了自定义聚合函数的想法。

使用 Visual Studio 创建数据库项目生成调用的 DLL

第一步新建项目:
2008版本选择 文件→新建→项目→SQL Server项目

 创建成功结果如下:

第二步新建项→聚合:

第三步:编写代码(实现字符串合并的函数代码如下)
聚合函数代码
using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text; [Serializable]
[SqlUserDefinedAggregate(
Format.UserDefined, //use clr serialization to serialize the intermediate result
IsInvariantToNulls = true, //optimizer property
IsInvariantToDuplicates = false, //optimizer property
IsInvariantToOrder = false, //optimizer property
MaxByteSize = 8000) //maximum size in bytes of persisted value
] public class Concatenate : IBinarySerialize
{
/// <summary>
/// The variable that holds the intermediate result of the concatenation
/// </summary>
private StringBuilder intermediateResult; /// <summary>
/// Initialize the internal data structures
/// </summary>
public void Init()
{
this.intermediateResult = new StringBuilder();
} /// <summary>
/// Accumulate the next value, not if the value is null
/// </summary>
/// <param name="value"></param>
public void Accumulate(SqlString value)
{
if (value.IsNull)
{
return;
} this.intermediateResult.Append(value.Value).Append(',');
} /// <summary>
/// Merge the partially computed aggregate with this aggregate.
/// </summary>
/// <param name="other"></param>
public void Merge(Concatenate other)
{
this.intermediateResult.Append(other.intermediateResult);
} /// <summary>
/// Called at the end of aggregation, to return the results of the aggregation.
/// </summary>
/// <returns></returns>
public SqlString Terminate()
{
string output = string.Empty;
//delete the trailing comma, if any
if (this.intermediateResult != null
&& this.intermediateResult.Length > 0)
{
output = this.intermediateResult.ToString(0, this.intermediateResult.Length - 1);
} return new SqlString(output);
} public void Read(BinaryReader r)
{
intermediateResult = new StringBuilder(r.ReadString());
} public void Write(BinaryWriter w)
{
w.Write(this.intermediateResult.ToString());
}
}
第四步:生成项目DLL并放于其他目录下面(非必须,C盘可能存在权限问题在注册时无法使用)
我放在F盘下面的这个路径

SQLserver 注册刚才编写的聚合函数 DLL

第一步:允许SQLserver安装外部程序集
数据库默认是不允许安装外部程序级的,需要通过sp_configure命令 修改clr enabled /*允许程序使用外部程序集*/
EXEC sp_configure 'clr enabled', 1
RECONFIGURE WITH OVERRIDE
GO
第二步:解决安全权限的配置引发的问题(不执行这一步就会触发安全权限配置问题)
具体链接安全问题链接:https://blog.csdn.net/weixin_34150503/article/details/92828414 /*sp_add_trusted_assembly的方式添加信任到数据库里去.*/
DECLARE @hash AS BINARY(64) = (SELECT HASHBYTES('SHA2_512', (SELECT * FROM OPENROWSET (BULK 'F:\ConactDll\Database3.dll', SINGLE_BLOB) AS [Data]))) 第三步:创建程序集与聚合函数
CREATE ASSEMBLY MyAgg FROM 'F:\ConactDll\Database3.dll'
WITH PERMISSION_SET = SAFE;
GO CREATE AGGREGATE MyAgg (@input nvarchar(200)) RETURNS nvarchar(max)
EXTERNAL NAME MyAgg.Concatenate; 注册完成之后系统数据库会出现我们自定义的聚合函数

SQL 中使用自定义聚合函数

select  dbo.myagg(需要合并的表字段)  结果 from   表  where 查询条件
使用效果如下:

额外篇

使用VS2019新建SQLserver数据库项目

第一步:创建项目



第二步:添加新项

后面就可以开始编写代码了,操作流程跟之前的 08 版本一样

最后附上已经写好的两个版本,需要的同学自取:https://pan.baidu.com/s/1encGUxiMpFcZXLum1zr3Ug 提取码: 8wyq

文章参考:https://dotblogs.com.tw/stanley14/2018/05/26/tsql_string_agg_insql2016

SQLserver 数据库自定义函数的更多相关文章

  1. sqlserver中自定义函数+存储过程实现批量删除

    由于项目的需要,很多模块都要实现批量删除的功能.为了方便模块的调用,把批量删除方法写成自定义函数.直接上代码. 自定义函数: ALTER FUNCTION [dbo].[func_SplitById] ...

  2. Jpa 重写方言dialect 使用oracle / mysql 数据库自定义函数

    在使用criteria api进行查询时 criteriaBuilder只提供了一个部分标准的sql函数,但当我们需要使用oracle特有的行转列函数wm_concat或 mysql特有的行转列函数g ...

  3. Postgre数据库自定义函数

    自定函数 1.查询函数: select prosrc from pg_proc where proname='test' 参数说明 : test 为函数名. 2.删除函数: drop function ...

  4. 用sqlserver的自定义函数直接获取多级部门全名

    好久没写存储过程了,今日正好同事的开发需要,实现显示多级部门的部门全名称. 如 财务部/会计部/会计一部   部门表 人员表 函数 getOrgAllName --OrgID 72 当前的部门ID A ...

  5. sqlserver 存储过程 自定义函数 游标???

    create proc cur_fun( @cur cursor --输入参数 ) as begin declare @mytpye tb1_type ) fetch next from @cur i ...

  6. orcl数据库自定义函数--金额小写转大写

    很多时候在打印票据的时候需要用到大写,ireport无法转换,只能先在查询语句里面进行转换,首先定义好函数,之后再调用函数 CREATE OR REPLACE Function MoneyToChin ...

  7. Oracle数据库自定义函数练习20181031

    --测试函数3 CREATE OR REPLACE FUNCTION FN_TEST3 (NUM IN VARCHAR2) RETURN VARCHAR2 IS TYPE VARCHAR2_ARR ) ...

  8. Sqlserver中存储过程,触发器,自定义函数(一)

    Sqlserver中存储过程,触发器,自定义函数 1.存储过程有关内容存储过程的定义:存储过程的分类:存储过程的创建,修改,执行:存储过程中参数的传递,返回与接收:存储过程的返回值:存储过程使用游标. ...

  9. Sqlserver中存储过程,触发器,自定义函数

    Sqlserver中存储过程,触发器,自定义函数: 1. 触发器:是针对数据库表或数据库的特殊存储过程,在某些行为发生的时候就会被激活 触发器的分类: DML触发器:发生在数据操作语言执行时触发执行的 ...

  10. 【转载】 Sqlserver中查看自定义函数被哪些对象引用

    Sqlserver数据库中支持自定义函数,包含表值函数和标量值函数,表值函数一般返回多个数据行即数据集,而标量值函数一般返回一个值,在数据库的存储过程中可调用自定义函数,也可在该自定义函数中调用另一个 ...

随机推荐

  1. Spring注解之构建器@Builder的用法

    简述 Builder使用创建者模式又叫建造者模式.简单来说,就是一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程. 基础使用 @Builder 注解为你的类生成相对略 ...

  2. 洛谷P1063

    [NOIP2006 提高组] 能量项链 题目描述 在 Mars 星球上,每个 Mars 人都随身佩带着一串能量项链.在项链上有 \(N\) 颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着 ...

  3. UE5 射线检测排除隐藏的Actor

    0x00 Unreal Engine 5(UE5)以其卓越的性能和直观的开发工具在游戏开发领域占据了重要地位.本系列将深入探讨UE5中射线检测的关键概念,着重介绍处理隐藏Actor的技巧. 0x01. ...

  4. 精品 IDEA 插件大汇总!值得收藏

    轻松提高 Java 开发效率 俗话说,工欲善其事,必先利其器.想要提升编程开发效率,必须选择一款顺手的开发工具. 对于 Java 开发者,JetBrains IDEA 无疑是目前最主流的开发工具,既简 ...

  5. 基于Java“镜头人生”约拍网站系统设计实现(源码+lw+部署文档+讲解等)

    \n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 系统介绍: 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件 ...

  6. 关于导入react native项目导致运行异常的那些事

    从git上导入公司的项目,在本地运行的时候,项目无法运行.sdk,jdk,node都是使用公司规定的版本,项目中的local.properties文件sdk.dir路径也换成了自己本地的目录,结果就在 ...

  7. RDD | 算子 | 持久化

    分布式集合对象上的API称之为算子 算子分为两类: transformation算子:指返回值仍然是rdd,类似于stream里的中间流 这类算子与中间流相同,是懒加载的 action算子:返回值不是 ...

  8. Hadoop 部署

    hadoop部署步骤: 环境rhel8.2 1.配置主机网络信息 使物理机能和主机ping通 使用secureCRT与虚拟连接 设置网卡(dhcp) [root@maoqiyang ~]# nmcli ...

  9. Linux网络问题排查

    Linux网络问题排查 用于排查Linux系统的网络故障. 网络排查一般是有一定的思路和顺序的,其实排查的思路就是根据具体的问题逐段排除故障可能发生的地方,最终确定问题. 所以首先要问一问,网络问题是 ...

  10. QT入门学习记录01

    目录 前言 一.Qt安装 二.创建一个Qt工程 三.基类的区别和常用函数 1.QWidget 1.1 设置窗口标题 1.2 设置窗口大小和显示位置 1.3 显示窗口 1.4 隐藏窗口 1.5 改变窗口 ...