sql - 解释这个 SQL 拆分函数的作用
问题描述
我对 SQL 还很陌生。我在网上找到了这个脚本。它在使用分隔符值拆分字符串值方面做得很好。
我可以看到他们声明了两个变量。之后的一切对我来说都没有多大意义。有人可以告诉我 fn_split_string_to_column 是如何工作的吗?
我怎么强调都不过分。我对此很陌生。
CREATE FUNCTION [dbo].[fn_split_string_to_column] (
@string NVARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @out_put TABLE (
[column_id] INT IDENTITY(1, 1) NOT NULL,
[value] NVARCHAR(MAX)
)
AS
BEGIN
DECLARE @value NVARCHAR(MAX),
@pos INT = 0,
@len INT = 0
SET @string = CASE
WHEN RIGHT(@string, 1) != @delimiter
THEN @string + @delimiter
ELSE @string
END
WHILE CHARINDEX(@delimiter, @string, @pos + 1) > 0
BEGIN
SET @len = CHARINDEX(@delimiter, @string, @pos + 1) - @pos
SET @value = SUBSTRING(@string, @pos, @len)
INSERT INTO @out_put ([value])
SELECT LTRIM(RTRIM(@value)) AS [column]
SET @pos = CHARINDEX(@delimiter, @string, @pos + @len) + 1
END
RETURN
END
GO
解决方案
它所做的是获取一个字符串,例如“让,做,这个”,并返回一个表,其结果是字符串中被给定字符分割的术语的索引。
像这样使用它:
select column_id, value
from fn_split_string_to_column('lets, do, this', ',');
虽然更多时候它是更大查询的一部分:
select st.col1,
st.col2,
termOrder = sp.column_id,
term = sp.value
from someTable st
cross apply fn_split_string_to_column(st.colToSplit, ',') sp;
请注意,sql server 2016 具有内置的拆分功能,但它不会为您提供术语排序(并且无法保证顺序),并且不会修剪条目:
select * from string_split('lets, do, this', ',');
至于这实际上是如何工作的,这里是该函数的注释版本:
CREATE FUNCTION [dbo].[fn_split_string_to_column] (
@string NVARCHAR(MAX), -- the string to be splitted
@delimiter CHAR(1) -- the character that tells you where to make the cuts
)
-- The result set will be a table, not a scalar value
RETURNS @out_put TABLE (
[column_id] INT IDENTITY(1, 1) NOT NULL, -- where the term occured in the string
[value] NVARCHAR(MAX) -- the splitted term
)
AS
BEGIN
DECLARE
@value NVARCHAR(MAX), -- holds the value of each segment (split in the string, result of substring)
@pos INT = 0, -- determines the starting position of a segment (for use in substring)
@len INT = 0 -- determines the length of the segment (for use in substring)
-- Ensure the passed-in string always ends with the delimiter character
-- This is so that the loop doesn't terminate prematurely
SET @string =
CASE
WHEN RIGHT(@string, 1) != @delimiter THEN @string + @delimiter
ELSE @string
END
-- while the length of the next segment would be positive ...
WHILE CHARINDEX(@delimiter, @string, @pos + 1) > 0
BEGIN
-- ... establish the length of the next segment to analyze
SET @len = CHARINDEX(@delimiter, @string, @pos + 1) - @pos
-- ... get the next segment to analyze
SET @value = SUBSTRING(@string, @pos, @len)
-- ... insert the segment as an entry into the results, ensuring it has no spaces surrounding it
INSERT INTO @out_put ([value])
SELECT LTRIM(RTRIM(@value)) AS [column]
-- ... in advance of the next loop, establish the starting position of the next segment
SET @pos = CHARINDEX(@delimiter, @string, @pos + @len) + 1
END
RETURN
END
推荐阅读
- excel - 检查2个条件后如何在表格中打印一个值
- python - 无法从数据框列表中获取索引位置
- ios - 如何从 RPScreenRecorder.shared().startCapture 中的 CMSampleBuffer 获取视频帧?
- java - java 8中避免多个并行if else循环的最佳方法
- c# - Microsoft.Azure.WebHosts.JobHostConfiguration 的替代品是什么
- javascript - 使用表单c#从javascript设置服务器端文本
- java - Jetty/Jersey:从 URI 中查找资源方法
- java - 将文件/“文件夹”锁定到特定的 JVM 并在锁定时进行迭代
- angular - 提交按钮变为未禁用,但在检查数字格式时未禁用
- unix - 从unix中的固定宽度文件中提取特定列