SQL常用自定义函数
1、字符串转Table(Func_SplitToTable)
CREATE FUNCTION [dbo].[Func_SplitToTable]
(
@SplitString NVARCHAR(MAX) ,
@Separator NVARCHAR(10) = ' '
)
RETURNS @SplitStringsTable TABLE
(
[id] INT IDENTITY(1, 1) ,
[value] NVARCHAR(MAX)
)
AS
BEGIN
DECLARE @CurrentIndex INT;
DECLARE @NextIndex INT;
DECLARE @ReturnText NVARCHAR(MAX);
SELECT @CurrentIndex = 1;
WHILE ( @CurrentIndex <= LEN(@SplitString) )
BEGIN
SELECT @NextIndex = CHARINDEX(@Separator, @SplitString, @CurrentIndex);
IF ( @NextIndex = 0
OR @NextIndex IS NULL
)
SELECT @NextIndex = LEN(@SplitString) + 1;
SELECT @ReturnText = SUBSTRING(@SplitString, @CurrentIndex,
@NextIndex - @CurrentIndex);
INSERT INTO @SplitStringsTable
( [value] )
VALUES ( @ReturnText );
SELECT @CurrentIndex = @NextIndex + 1;
END;
RETURN;
END;
二.JSON转Table(Func_ParseJSONToTable,JsonToTable,Func_PivotToNewTable)
一.JSON转Table
ALTER FUNCTION [dbo].[Func_ParseJSONToTable] ( @JSON NVARCHAR(MAX) )
RETURNS @TX TABLE
(
element_id INT IDENTITY(1, 1)
NOT NULL ,
sequenceNo [INT] NULL ,
parent_ID INT ,
Object_ID INT ,
Tx_NAME NVARCHAR(2000) ,
StringValue NVARCHAR(MAX) NOT NULL ,
ValueType VARCHAR(10) NOT NULL
)
AS
BEGIN
DECLARE @FirstObject INT ,
@OpenDelimiter INT ,
@NextOpenDelimiter INT ,
@NextCloseDelimiter INT ,
@Type NVARCHAR(10) ,--
@NextCloseDelimiterChar CHAR(1) ,
@Contents NVARCHAR(MAX) ,
@Start INT ,
@end INT ,
@param INT ,
@EndOfName INT ,
@token NVARCHAR(200) ,
@value NVARCHAR(MAX) ,
@SequenceNo INT ,
@name NVARCHAR(200) ,
@parent_ID INT ,
@lenJSON INT ,
@characters NCHAR(36) ,
@result BIGINT ,
@index SMALLINT ,
@Escape INT;
DECLARE @Strings TABLE
(
String_ID INT IDENTITY(1, 1) ,
StringValue NVARCHAR(MAX)
);
SELECT--initialise the characters to convert hex to ascii
@characters = '0123456789abcdefghijklmnopqrstuvwxyz' ,
@SequenceNo = 0 , --set the sequence no. to something sensible.
@parent_ID = 0;
WHILE 1 = 1 --forever until there is nothing more to do
BEGIN
SELECT @Start = PATINDEX('%[^a-zA-Z]["]%',
@JSON COLLATE SQL_Latin1_General_CP850_Bin);--next delimited string
IF @Start = 0
BREAK; --no more so drop through the WHILE loop
IF SUBSTRING(@JSON, @Start + 1, 1) = '"'
BEGIN --Delimited Name
SET @Start = @Start + 1;
SET @end = PATINDEX('%[^\]["]%',
RIGHT(@JSON,
LEN(@JSON + '|') - @Start));
END;
IF @end = 0 --no end delimiter to last string
BREAK; --no more
SELECT @token = SUBSTRING(@JSON, @Start + 1, @end - 1);
SELECT @token = REPLACE(@token, FromString, ToString)
FROM ( SELECT '\"' AS FromString ,
'"' AS ToString
UNION ALL
SELECT '\\' ,
'\'
UNION ALL
SELECT '\/' ,
'/'
UNION ALL
SELECT '\b' ,
CHAR(08)
UNION ALL
SELECT '\f' ,
CHAR(12)
UNION ALL
SELECT '\n' ,
CHAR(10)
UNION ALL
SELECT '\r' ,
CHAR(13)
UNION ALL
SELECT '\t' ,
CHAR(09)
) substitutions;
SELECT @result = 0 ,
@Escape = 1;
WHILE @Escape > 0
BEGIN
SELECT @index = 0 ,
@Escape = PATINDEX('%\x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]%',
@token);
IF @Escape > 0 --if there is one
BEGIN
WHILE @index < 4
BEGIN
SELECT --determine its value
@result = @result + POWER(16,
@index)
* ( CHARINDEX(SUBSTRING(@token,
@Escape + 2 + 3
- @index, 1),
@characters) - 1 ) ,
@index = @index + 1;
END;
SELECT @token = STUFF(@token, @Escape, 6,
NCHAR(@result));
END;
END;
INSERT INTO @Strings
( StringValue )
SELECT @token;
SELECT @JSON = STUFF(@JSON, @Start, @end + 1,
'@string'
+ CONVERT(NVARCHAR(5), @@identity));
END;
WHILE 1 = 1 --forever until there is nothing more to do
BEGIN
SELECT @parent_ID = @parent_ID + 1;
SELECT @FirstObject = PATINDEX('%[{[[]%',
@JSON COLLATE SQL_Latin1_General_CP850_Bin);--object or array
IF @FirstObject = 0
BREAK;
IF ( SUBSTRING(@JSON, @FirstObject, 1) = '{' )
SELECT @NextCloseDelimiterChar = '}' ,
@Type = 'object';
ELSE
SELECT @NextCloseDelimiterChar = ']' ,
@Type = 'array';
SELECT @OpenDelimiter = @FirstObject;
WHILE 1 = 1 --find the innermost object or list...
BEGIN
SELECT @lenJSON = LEN(@JSON + '|') - 1;
SELECT @NextCloseDelimiter = CHARINDEX(@NextCloseDelimiterChar,
@JSON,
@OpenDelimiter
+ 1);
SELECT @NextOpenDelimiter = PATINDEX('%[{[[]%',
RIGHT(@JSON,
@lenJSON
- @OpenDelimiter)COLLATE SQL_Latin1_General_CP850_Bin);--object
IF @NextOpenDelimiter = 0
BREAK;
SELECT @NextOpenDelimiter = @NextOpenDelimiter
+ @OpenDelimiter;
IF @NextCloseDelimiter < @NextOpenDelimiter
BREAK;
IF SUBSTRING(@JSON, @NextOpenDelimiter, 1) = '{'
SELECT @NextCloseDelimiterChar = '}' ,
@Type = 'object';
ELSE
SELECT @NextCloseDelimiterChar = ']' ,
@Type = 'array';
SELECT @OpenDelimiter = @NextOpenDelimiter;
END;
SELECT @Contents = SUBSTRING(@JSON, @OpenDelimiter + 1,
@NextCloseDelimiter
- @OpenDelimiter - 1);
SELECT @JSON = STUFF(@JSON, @OpenDelimiter,
@NextCloseDelimiter - @OpenDelimiter + 1,
'@' + @Type
+ CONVERT(NVARCHAR(5), @parent_ID));
WHILE ( PATINDEX('%[A-Za-z0-9@+.e]%',
@Contents COLLATE SQL_Latin1_General_CP850_Bin) ) <> 0
BEGIN
IF @Type = 'Object'
BEGIN
SELECT @SequenceNo = 0 ,
@end = CHARINDEX(':', ' ' + @Contents);
SELECT @Start = PATINDEX('%[^A-Za-z@][@]%',
' ' + @Contents);--AAAAAAAA
SELECT @token = SUBSTRING(' ' + @Contents,
@Start + 1,
@end - @Start - 1) ,
@EndOfName = PATINDEX('%[0-9]%',
@token COLLATE SQL_Latin1_General_CP850_Bin) ,
@param = RIGHT(@token,
LEN(@token)
- @EndOfName + 1);
SELECT @token = LEFT(@token, @EndOfName - 1) ,
@Contents = RIGHT(' ' + @Contents,
LEN(' ' + @Contents
+ '|') - @end
- 1);
SELECT @name = StringValue
FROM @Strings
WHERE String_ID = @param; --fetch the name
END;
ELSE
SELECT @name = NULL ,
@SequenceNo = @SequenceNo + 1;
SELECT @end = CHARINDEX(',', @Contents);
IF @end = 0
SELECT @end = PATINDEX('%[A-Za-z0-9@+.e][^A-Za-z0-9@+.e]%',
@Contents + ' ') + 1;
SELECT @Start = PATINDEX('%[^A-Za-z0-9@+.e][A-Za-z0-9@+.e]%',
' ' + @Contents);
--select @start,@end, LEN(@contents+'|'), @contents
SELECT @value = RTRIM(SUBSTRING(@Contents, @Start,
@end - @Start)) ,
@Contents = RIGHT(@Contents + ' ',
LEN(@Contents + '|') - @end);
IF SUBSTRING(@value, 1, 7) = '@object'
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
Object_ID ,
ValueType
)
SELECT @name ,
@SequenceNo ,
@parent_ID ,
SUBSTRING(@value, 8, 5) ,
SUBSTRING(@value, 8, 5) ,
'object';
ELSE
IF SUBSTRING(@value, 1, 6) = '@array'
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
Object_ID ,
ValueType
)
SELECT @name ,
@SequenceNo ,
@parent_ID ,
SUBSTRING(@value, 7, 5) ,
SUBSTRING(@value, 7, 5) ,
'array';
ELSE
IF SUBSTRING(@value, 1, 7) = '@string'
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
ValueType
)
SELECT @name ,
@SequenceNo ,
@parent_ID ,
StringValue ,
'string'
FROM @Strings
WHERE String_ID = SUBSTRING(@value,
8, 5);
ELSE
IF @value IN ( 'true', 'false' )
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
ValueType
)
SELECT @name ,
@SequenceNo ,
@parent_ID ,
@value ,
'boolean';
ELSE
IF @value = 'null'
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
ValueType
)
SELECT @name ,
@SequenceNo ,
@parent_ID ,
@value ,
'null';
ELSE
IF PATINDEX('%[^0-9]%',
@value COLLATE SQL_Latin1_General_CP850_Bin) > 0
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
ValueType
)
SELECT
@name ,
@SequenceNo ,
@parent_ID ,
@value ,
'real';
ELSE
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
ValueType
)
SELECT
@name ,
@SequenceNo ,
@parent_ID ,
@value ,
'int';
IF @Contents = ' '
SELECT @SequenceNo = 0;
END;
END;
INSERT INTO @TX
( Tx_NAME ,
sequenceNo ,
parent_ID ,
StringValue ,
Object_ID ,
ValueType
)
SELECT '-' ,
1 ,
NULL ,
'' ,
@parent_ID - 1 ,
isnull(@Type,'');
RETURN;
END;
二.行转列
CREATE FUNCTION [dbo].[Func_PivotToNewTable]
(
@Json VARCHAR(MAX) ,--json字符串
@ColumnName VARCHAR(MAX) --列名
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @SQL VARCHAR(MAX);
SET @SQL = 'DECLARE @table AS JsonToTable ';
SET @SQL = @SQL + ' INSERT INTO @table';
SET @SQL = @SQL + ' SELECT * FROM [Func_ParseJSONToTable](''' + @Json
+ ''')';
SET @SQL = @SQL + ' SELECT '+@ColumnName+' FROM ( SELECT Parent_ID ,
Tx_NAME ,
StringValue
FROM @table
WHERE SequenceNo = 0
) p PIVOT( MAX([StringValue]) FOR Tx_NAME IN ( ' + @ColumnName
+ ' ) )AS pvt';
RETURN @SQL;
END;
二.用户自定义类型
CREATE TYPE [dbo].[JsonToTable] AS TABLE(
[RowID] [int] IDENTITY(1,1) NOT NULL,
[Element_id] [int] NULL,
[SequenceNo] [int] NULL,
[Parent_ID] [int] NULL,
[Object_ID] [int] NULL,
[Tx_NAME] [nvarchar](2000) NULL,
[StringValue] [nvarchar](max) NOT NULL,
[ValueType] [varchar](10) NOT NULL
)
3、全角半角转化
--===================================
-- Author:Crazier
-- Create Date: 2018-3-28
-- Version: 1.0.0.0
-- Title: 字符全角半角转换
-- Description: 创建
-- EXEC: SELECT Func_CommConvertWordAngle_New ( '7',0)
--====================================
CREATE FUNCTION Func_CommConvertWordAngle_New
(
@str NVARCHAR(4000) , --要转换的字符串
@flag BIT --转换标志,0转换成半角,1转换成全角
)
RETURNS NVARCHAR(4000)
AS
BEGIN
DECLARE @pat NVARCHAR(8) ,
@step INT ,
@i INT ,
@spc INT;
IF @flag = 0
SELECT @pat = N'%[!-~]%' ,
@step = -65248 ,
@str = REPLACE(@str, N' ', N' ');
ELSE
SELECT @pat = N'%[!-~]%' ,
@step = 65248 ,
@str = REPLACE(@str, N' ', N' ');
SET @i = PATINDEX(@pat COLLATE Latin1_General_BIN, @str);
WHILE @i > 0
SELECT @str = REPLACE(@str, SUBSTRING(@str, @i, 1),
NCHAR(UNICODE(SUBSTRING(@str, @i, 1))
+ @step)) ,
@i = PATINDEX(@pat COLLATE Latin1_General_BIN, @str);
RETURN(@str);
END;
GO
SQL常用自定义函数的更多相关文章
- sql server 自定义函数的使用
sql server 自定义函数的使用 自定义函数 用户定义自定义函数像内置函数一样返回标量值,也可以将结果集用表格变量返回 用户自定义函数的类型: 标量函数:返回一个标量值 表格值函数{内联表格值函 ...
- 13、SQL Server 自定义函数
SQL Server 自定义函数 在SQL Server中不仅可以使用系统函数(如:聚合函数,字符串函数,时间日期函数等)还可以根据需要自定义函数. 自定义函数分为标量值函数和表值函数. 其中,标量值 ...
- SQL Server 自定义函数(Function)——参数默认值
sql server 自定义函数分为三种类型:标量函数(Scalar Function).内嵌表值函数(Inline Function).多声明表值函数(Multi-Statement Functio ...
- 【SQL Server】SQL常用系统函数
SQL常用系统函数 函数类型 函数表达式 功能 应用举例 字符串函数 SubString(表达式,起始,长度) 取子串 SubString('ABCDEFG',3,4) Right(表达式,长度) 右 ...
- JS常用自定义函数总结
JS常用自定义函数总结 1.原生JavaScript实现字符串长度截取 2.原生JavaScript获取域名主机 3.原生JavaScript清除空格 4.原生JavaScript替换全部 5.原 ...
- 也来谈谈SQL SERVER 自定义函数~
在使用SQL SERVER 数据库的时候,函数大家都应该用过,简单的比如 系统聚合函数 Sum(),Max() 等等.但是一些初学者编写自定义函数的时候,经常问起什么是表值函数,什么是标量值函数. 表 ...
- SQL Server自定义函数( 转载于51CTO )
用户自定义函数自定义函数不能执行一系列改变数据库状态的操作,可以像系统函数在查询或存储过程等的程序中使用,也可以像相信过程一样能过 execute 命令来执行.自定义函数中存储了一个 Transact ...
- sql server自定义函数学习笔记
sql server中函数分别有:表值函数.标量函数.聚合函数.系统函数.这些函数中除系统函数外其他函数都需要用户进行自定义. 一.表值函数 简单表值函数 创建 create function fu_ ...
- SQL Function 自定义函数
目录 产生背景(已经有了存储过程,为什么还要使用自定义函数) 发展历史 构成 使用方法 适用范围 注意事项 疑问 内容 产生背景(已经有了存储过程,为什么还要使用自定义函数) 与存储过程的区别(存 ...
随机推荐
- 在Eclipse中tomcat 内存配置
修改1: 在Eclipse中下面Servers双击Tomcat Server... 然后点击General InformAtion 下的Open launch configuration: 会弹出Ed ...
- SQL Server 2012 从备份中还原数据库
1.首先把原数据库备份,检查原数据库的日志文件是否太大,如果过于大应该先收缩数据库日志 2.把备份的数据库文件在目标SQL Server还原,点击数据库,选择“还原文件或文件组” 3.如果需要修改还原 ...
- shell网络管理
背景知识 联网就是通过网络将主机进行互联并采用不同的规范配置网络上的节点.我们以 TCP/IP 作为网络栈,所有的操作都是基于它进行的.网络是计算机系统中重要的部分.连接在网络上的每个节点都分配了一个 ...
- HDU - 4333 Revolving Digits(拓展kmp+最小循环节)
1.给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s.求这个过程中比原来的数字小的.相等的.大的数字各有多少. 例如:字符串123,变换过程:123 -> ...
- I.MX6 DNS 查看、修改方法
/************************************************************************** * I.MX6 DNS 查看.修改方法 * 说明 ...
- 使用 MongoDB 存储商品分类信息
此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 这是一篇MongoDB官网上的一篇文章,分析了使用MongoDB存储商品分类信息相比其他数据库的优势,并讲述 ...
- PCB Redis的安装使用
记录一下Redis的安装与基本使用 一.Redis简介 Redis(REmote DIctionary Server)远程字典服务器,免费开源,是一个高性能的(Key/Value)分布式内存数据库.其 ...
- bzoj 1858: [Scoi2010]序列操作【线段树】
合并中间那块的时候没取max--WAWAWA 在线段树上维护一堆东西,分别是len区间长度,sm区间内1的个数,ll0区间从左开始最长连续0,ml0区间中间最长连续0,rl0区间从右开始最长连续0,l ...
- bzoj 4080: [Wf2014]Sensor Network【瞎搞+随机化】
参考:https://blog.csdn.net/YihAN_Z/article/details/73380387 一点都不想写正解.jpg random_shuffle一下然后贪心的加点,和ans取 ...
- Luogu P1197 [JSOI2008]星球大战 By cellur925
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧 ...