首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> SQL Server 2005

T-SQL 分隔字串第 N 片段更新:單一陳述式實作字串分段修改

     編輯:SQL Server 2005

需求場景

資料欄位儲存以特定分隔符號(如逗號、分號、管線符)串接的多值字串,需**僅更新第 N 個片段**,其餘保持不動。例如:'a,b,c,d,e' → 將第 3 片段改為 'test' → 'a,b,test,d,e'。

核心邏輯:定位第 N 片段的起始/結束位置

  1. 在字串尾端附加一個分隔符,確保 CHARINDEX 一定能找到下一個分隔符。
  2. 迴圈 @pos 次:每輪將搜尋起點移至上一個分隔符之後。
  3. 迴圈結束時,@I = 目標片段起始位置,@J = 目標片段結束位置(下一分隔符位置)。
  4. 依三種邊界情況執行 STUFF 替換:

完整可執行範例

DECLARE 
    @s VARCHAR(8000) = 'a,b,c,d,e',   -- 原字串
    @split CHAR(1) = ',',              -- 分隔符
    @pos INT = 3,                      -- 目標片段序號(1-based)
    @value VARCHAR(100) = 'test',      -- 新值
    @splitlen INT,
    @i INT, @j INT;

SELECT @splitlen = LEN(@split + 'x') - 2,  -- 分隔符實際長度(支援多字元分隔符)
       @i = 1,
       @j = CHARINDEX(@split, @s + @split); -- 首個分隔符位置

-- 迴圈定位第 @pos 個片段
WHILE @pos > 0 AND @i <= @j
BEGIN
    SELECT @pos = @pos - 1,
           @i = @j + @splitlen + 1,
           @j = CHARINDEX(@split, @s + @split, @i);
END

-- 依邊界情況替換
SELECT @s = CASE
    WHEN @i < @j        THEN STUFF(@s, @i, @j - @i, @value)          -- 中間片段
    WHEN @j > LEN(@s)   THEN @s + @value                              -- 尾端新增(原無第 N 片段)
    WHEN @i = @j        THEN STUFF(@s, @i, 0, @value)                 -- 空片段插入
    ELSE @s END;

SELECT @s AS Result;  -- 輸出: a,b,test,d,e

關鍵函數說明

進階擴充:封裝為純量函數

CREATE FUNCTION dbo.fn_UpdateSegment
(
    @Input VARCHAR(8000),
    @Delimiter VARCHAR(10),
    @Segment INT,
    @NewValue VARCHAR(8000)
)
RETURNS VARCHAR(8000)
AS
BEGIN
    DECLARE @dl INT = LEN(@Delimiter),
            @i INT = 1,
            @j INT = CHARINDEX(@Delimiter, @Input + @Delimiter),
            @pos INT = @Segment;

    WHILE @pos > 0 AND @i <= @j
    BEGIN
        SET @pos -= 1;
        SET @i = @j + @dl;
        SET @j = CHARINDEX(@Delimiter, @Input + @Delimiter, @i);
    END

    RETURN CASE
        WHEN @i < @j        THEN STUFF(@Input, @i, @j - @i, @NewValue)
        WHEN @j > LEN(@Input) THEN @Input + @Delimiter + @NewValue
        WHEN @i = @j        THEN STUFF(@Input, @i, 0, @NewValue)
        ELSE @Input END;
END;
GO

-- 使用範例
SELECT dbo.fn_UpdateSegment('a|b|c|d', '|', 2, 'NEW') AS Result; -- a|NEW|c|d

效能與限制提醒

  • 純 T-SQL 迴圈,適用於**單列/少量列**更新;大批量資料建議改用 CLR 函數或應用層處理。
  • 支援多字元分隔符(如 '||'、'::')。
  • 若 @Segment 超過實際片段數,行為為「尾端附加分隔符 + 新值」。
  • 若原字串為 NULL,函數回傳 NULL;建議呼叫端先 ISNULL。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數用途
CHARINDEX(sub, str, start)從 start 位置尋找 sub 首次出現位置
STUFF(str, start, len, new)刪除 str 從 start 長度 len 的字元,插入 new
LEN(str)字串長度(不含尾端空白)