T-SQL 內建無 SPLIT 函數,本文提供兩個生產級純量函數:取得分割後長度、依索引取值。
CREATE FUNCTION dbo.Get_StrArrayLength
(
@str VARCHAR(5000), -- 待分割字串
@split VARCHAR(10) -- 分隔符
)
RETURNS INT
AS
BEGIN
DECLARE @location INT, @start INT, @length INT;
SET @str = LTRIM(RTRIM(@str));
SET @location = CHARINDEX(@split, @str);
SET @length = 1; -- 至少有一個元素
WHILE @location <> 0
BEGIN
SET @start = @location + 1;
SET @location = CHARINDEX(@split, @str, @start);
SET @length = @length + 1;
END
RETURN @length;
END;
CREATE FUNCTION dbo.Get_StrArrayStrOfIndex
(
@str VARCHAR(5000),
@split VARCHAR(10),
@index INT -- 1-based 索引
)
RETURNS VARCHAR(5000)
AS
BEGIN
DECLARE @location INT, @start INT, @next INT, @seed INT;
SET @str = LTRIM(RTRIM(@str));
SET @start = 1;
SET @next = 1;
SET @seed = LEN(@split);
SET @location = CHARINDEX(@split, @str);
WHILE @location <> 0 AND @index > @next
BEGIN
SET @start = @location + @seed;
SET @location = CHARINDEX(@split, @str, @start);
SET @next = @next + 1;
END
-- 處理最後一個元素或無分隔符情況
IF @location = 0
SET @location = LEN(@str) + 1;
RETURN SUBSTRING(@str, @start, @location - @start);
END;
' 取得長度
SELECT dbo.Get_StrArrayLength('1,2,3,4,5', ','); -- 返回 5
' 取得第 3 個元素
SELECT dbo.Get_StrArrayStrOfIndex('apple|banana|cherry|date', '|', 3); -- 返回 'cherry'
' 邊界測試
SELECT dbo.Get_StrArrayStrOfIndex('single', ',', 1); -- 'single'
SELECT dbo.Get_StrArrayStrOfIndex('a,b,c', ',', 5); -- '' (空字串,索引超界)
| 項目 | 說明 |
|---|---|
| 最大長度 | 參數 VARCHAR(5000),需更長請改 VARCHAR(MAX) 並調整邏輯 |
| 分隔符長度 | 支援多字元分隔符 (如 ||、###) |
| 索引超界 | 返回空字串,不拋錯誤 (可依需求改為 NULL 或 RAISERROR) |
| 並發安全 | 純量函數無副作用,完全安全 |
' STRING_SPLIT (僅返回值,無索引/順序保證)
SELECT value FROM STRING_SPLIT('a,b,c', ',');
' JSON 解析技巧 (保持順序、可取索引)
DECLARE @json NVARCHAR(MAX) = '["a","b","c"]';
SELECT JSON_VALUE(@json, '$[2]'); -- 索引 0-based,返回 'c'
' OPENJSON (完整功能)
SELECT [key], value FROM OPENJSON('["a","b","c"]'); -- key 為 0-based 索引
STRING_SPLIT / OPENJSON**,原生、高效、無維護成本String.Split) 或應用層分割後傳入 TVP字串分割是常見需求,**善用內建功能、版本適配、效能分層**是專業開發態度。