这是一个SQL Server标量值函数,用于提取层级码字符串的父级编码:
以下是修改后的SQL Server标量值函数,将分隔符作为变量参数:
CREATE FUNCTION dbo.GetParentLevelCode
(
@LevelCode NVARCHAR(100), -- 输入层级码
@Separator NVARCHAR(10) = '.' -- 分隔符,默认为点号
)
RETURNS NVARCHAR(100)
AS
BEGIN
DECLARE @Result NVARCHAR(100)
-- 如果输入为空或空字符串,直接返回空
IF @LevelCode IS NULL OR LTRIM(RTRIM(@LevelCode)) = ''
RETURN ''
-- 如果分隔符为空,使用默认的点号
IF @Separator IS NULL OR LTRIM(RTRISeparator)) = ''
SET @Separator = '.'
-- 查找最后一个分隔符的位置
DECLARE @LastSepPos INT
-- 使用REVERSE和CHARINDEX查找最后一个分隔符的位置
SET @LastSepPos = CASE
WHEN CHARINDEX(@Separator, @LevelCode) > 0 THEN
LEN(@LevelCode) - CHARINDEX(REVERSE(@Separator), REVERSE(@LevelCode)) - LEN(@Separator) + 2
ELSE 0
END
-- 如果没有找到分隔符,返回空字符串(表示没有父级)
IF @LastSepPos = 0
RETURN ''
-- 提取最后一个分隔符之前的部分
SET @Result = LEFT(@LevelCode, @LastSepPos - 1)
RETURN @Result
END
使用示例:
-- 使用默认分隔符(点号)
SELECT dbo.GetParentLevelCode('1.1.1', DEFAULT) -- 返回: 1.1
SELECT dbo.GetParentLevelCode('1.1.2.1', '.') -- 返回: 1.1.2
-- 使用不同的分隔符
SELECT dbo.GetParentLevelCode('1-1-1', '-') -- 返回: 1-1
SELECT dbo.GetParentLevelCode('1/1/2/1', '/') -- 返回: 1/1/2
SELECT dbo.GetParentLevelCode('A_B_CD', '') -- 返回: A_B_C
-- 多字符分隔符
SELECT dbo.GetParentLevelCode('1->1->2->1', '->') -- 返回: 1->1->2
更简洁的版本(使用递归CTE方法):
CREATE FUNCTION dbo.GetParentLevelCode_CTE
(
@LevelCode NVARCHAR(100),
@Separator NVARCHAR(10) = '.'
)
RETURNS NVARCHAR(100)
AS
BEGIN
-- 如果输入为空,返回空
IF @LevelCode IS NULL OR LTRIM(RTRIM(@LevelCode)) = ''
RETURN ''
-- 如果分隔符为空,使用默认的点号
IF @Separator IS NULL OR LTRIM(RTRIM(@Separator)) = ''
SET @Separator = '.'
DECLARE @Result NVARCHAR(100)
-- 使用递归CTE分割字符串
WITH SplitCTE AS (
SELECT
1 AS Position,
CHARINDEX(@Separator, @LevelCode + @Separator) AS SepPos,
SUBSTRING(@LevelCode, 1, CHARINDEX(@Separator, @LevelCode + @Separator) - 1) AS Part,
SUBSTRING(@LevelCode, CHARINDEX(@Separator, @LevelCode + @Separator) + LEN(@Separator), LEN(@LevelCode)) AS Remainder
UNION ALL
SELECT
Position + 1,
CHARINDEX(@Separator, Remainder + @Separator),
SUBSTRING(Remainder, 1, CHARINDEX(@Separator, Remainder + @Separator) - 1),
SUBSTRING(Remainder, CHARINDEX(@Separator, Remainder + @Separator) + LEN(@Separator), LEN(Remainder))
FROM SplitCTE
WHERE CHARINDEX(@Separator, Remainder + @Separator) > 0
),
PartsCTE AS (
SELECT Position, Part,
ROW_NUMBER() OVER (ORDER BY Position) AS rn,
COUNT(*) OVER () AS TotalParts
FROM SplitCTE
)
SELECT @Result = (
SELECT Part + CASE WHEN Position < TotalParts - 1 THEN @Separator ELSE '' END
FROM PartsCTE
WHERE Position < TotalParts
ORDER BY Position
FOR XML PATH('')
)
RETURN @Result
END
最简单的版本(使用字符串函数):
CREATE FUNCTION dbo.GetParentLevelCode_Simple
(
@LevelCode NVARCHAR(100),
@Separator NVARCHAR(10) = '.'
)
RETURNS NVARCHAR(100)
AS
BEGIN
-- 如果输入为空,返回空
IF @LevelCode IS NULL OR LTRIM(RTRIM(@LevelCode)) = ''
RETURN ''
-- 如果分隔符为空,使用默认的点号
IF @Separator IS NULL OR LTRIM(RTRIM(@Separator)) = ''
SET @Separator = '.'
-- 查找最后一个分隔符的位置
DECLARE @LastSepPos INT
SET @LastSepPos = LEN(@LevelCode) - CHARINDEX(REVERSE(@Separator), REVERSE(@LevelCode)) + 1
-- 如果没有分隔符,返回空字符串
IF @LastSepPos = LEN(@LevelCode) + 1 OR @LastSepPos = 0
RETURN ''
-- 提取最后一个分隔符之前的部分
RETURN LEFT(@LevelCode, @LastSepPos - 1)
END
推荐使用最简单的版本,因为它效率最高且逻辑清晰。您可以根据需要选择适合的版本。
