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

SQL Server STUFF 函數完整指南:語法、參數、實戰範例與進階應用

     編輯:關於SqlServer

函數定義與語法

STUFF ( character_expression , start , length , replacement_expression )

在 character_expression 中,從 start 位置刪除 length 個字元,並插入 replacement_expression。回傳型別與輸入字元表達式型別一致 (字元型回傳字元,二進位型回傳二進位)。

參數詳細說明

參數資料型別說明邊界行為
character_expression字元/二進位型別 (常數/變數/欄位)目標字串若為 NULL → 回傳 NULL
startINT / BIGINT刪除/插入起始位置 (1-based)≤ 0 或 > LEN(character_expression) → 回傳空字串 ''
lengthINT / BIGINT要刪除的字元數< 0 → 空字串; > 剩餘長度 → 刪除至字串結尾
replacement_expression字元/二進位型別插入的新字串若為 NULL → 僅刪除不插入 (相當 REPLACE 為空)

基礎範例

-- 經典範例:abcdef 從第 2 字元刪 3 個 (bcd) 插入 ijklmn
SELECT STUFF('abcdef', 2, 3, 'ijklmn');  -- 結果:aijklmnef

-- 僅刪除不插入 (replacement 為空字串)
SELECT STUFF('abcdef', 2, 3, '');        -- 結果:aef

-- 僅插入不刪除 (length = 0)
SELECT STUFF('abcdef', 3, 0, 'XYZ');     -- 結果:abXYZcdef

-- 起始位置超過長度
SELECT STUFF('abc', 5, 1, 'X');          -- 結果:'' (空字串)

-- 負數參數
SELECT STUFF('abc', -1, 2, 'X');         -- 結果:''

實戰應用場景

1. 字串格式化:身分證/電話/信用卡號碼遮罩

-- 身分證字號:保留首碼與末 3 碼,中間遮罩
DECLARE @ID VARCHAR(10) = 'A123456789';
SELECT STUFF(@ID, 2, LEN(@ID)-4, REPLICATE('*', LEN(@ID)-4)); -- A*******89

-- 手機號碼:保留前 3 後 4
DECLARE @Phone VARCHAR(10) = '0912345678';
SELECT STUFF(@Phone, 4, 4, '****'); -- 091****5678

2. 動態 SQL 建構:移除尾端分隔符

DECLARE @Cols NVARCHAR(MAX) = N'Col1, Col2, Col3, ';
-- 移除最後的逗號空白
SELECT STUFF(@Cols, LEN(@Cols) - 1, 2, ''); -- Col1, Col2, Col3

-- 實際動態 SQL 組裝模式
DECLARE @SQL NVARCHAR(MAX) = N'SELECT ' + STUFF(@Cols, LEN(@Cols) - 1, 2, '') + N' FROM dbo.Table1;';

3. 日期時間格式轉換 (舊版相容)

-- 將 20240115 轉為 2024-01-15
DECLARE @DateStr CHAR(8) = '20240115';
SELECT STUFF(STUFF(@DateStr, 5, 0, '-'), 8, 0, '-'); -- 2024-01-15

4. XML/JSON 片段修改

DECLARE @XML XML = N'AB';
-- 將第一個 item 的 id 從 1 改為 100 (示範字串操作,實際建議用 modify())
DECLARE @XMLStr NVARCHAR(MAX) = CAST(@XML AS NVARCHAR(MAX));
SELECT STUFF(@XMLStr, CHARINDEX('id="1"', @XMLStr) + 4, 1, '100');

5. 批次字串組裝:FOR XML PATH 配合 STUFF 產生逗號分隔清單

-- 經典模式:取得某資料表所有欄位名稱逗號分隔
SELECT STUFF((
    SELECT N', ' + QUOTENAME(name)
    FROM sys.columns
    WHERE object_id = OBJECT_ID('dbo.YourTable')
    ORDER BY column_id
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 2, ''); -- 移除開頭 ", "
-- 結果:[Col1], [Col2], [Col3]...

進階技巧與注意事項

主題說明
二進位資料操作STUFF(0x123456, 2, 1, 0xAB) → 0x12AB56,適用於二進位欄位局部修改。
搭配 REPLACE 差異REPLACE 替換**所有**符合子字串;STUFF 針對**指定位置/長度**精準手術。
效能考量純量函數,大量列逐列呼叫有函數開銷。集合操作優先用集合邏輯 (如 FOR XML PATH)。
結果長度溢位若結果超過目標型別最大長度 (如 VARCHAR(8000)) 會報錯。大字串用 VARCHAR(MAX)。
NULL 處理任一參數為 NULL → 回傳 NULL (依 ANSI_NULLS)。建議 ISNULL/COALESCE 預處理。

常見錯誤與除錯

  • 起始位置 0:SQL Server 字串位置從 **1** 開始,非 0。STUFF(@s, 0, 1, 'X') 回傳空字串。
  • 長度負數:length < 0 直接回傳空字串,不報錯但邏輯錯誤。
  • 型別不匹配character_expression 為 VARCHAR 但 replacement 為 NVARCHAR → 隱含轉換可能導致截斷或排序規則衝突。顯式 CAST 統一型別。

結語

STUFF 是 T-SQL 字串處理的「精密手術刀」:**指定位置、指定長度、精準替換**。掌握其邊界行為 (負數、超長、NULL)、搭配 LEN/CHARINDEX/FOR XML PATH 等函數,即可優雅解決「移除尾端分隔符、遮罩敏感資訊、動態 SQL 組裝、格式轉換」等高頻需求。記住:**位置從 1 起算、長度可為 0 (純插入)、替換字串可為空 (純刪除)**,三種基本模式組合出無限變化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved