You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server 2012中如何在SELECT语句中仅保留VARCHAR列的指定有效字符?

解决方案

针对SQL Server 2012中保留指定有效字符的需求,推荐两种灵活的实现方案:

方案一:自定义标量函数(推荐,高灵活性)

创建可复用的函数,接收输入字符串和有效字符集合,逐字符检查并保留有效字符,后续修改有效字符只需调整调用参数即可。

1. 创建清理函数

CREATE FUNCTION dbo.CleanInvalidChars
(
    @InputString VARCHAR(MAX),
    @ValidChars VARCHAR(100) -- 传入需要保留的有效字符集合
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @CleanString VARCHAR(MAX) = '';
    DECLARE @Position INT = 1;
    
    WHILE @Position <= LEN(@InputString)
    BEGIN
        DECLARE @CurrentChar CHAR(1) = SUBSTRING(@InputString, @Position, 1);
        -- 如需严格区分大小写,可去掉UPPER转换
        IF CHARINDEX(UPPER(@CurrentChar), UPPER(@ValidChars)) > 0
        BEGIN
            SET @CleanString = @CleanString + @CurrentChar;
        END
        SET @Position = @Position + 1;
    END
    
    RETURN @CleanString;
END
GO

2. 使用函数查询

调用时直接传入目标字符串和有效字符集合,示例:

DECLARE @table AS TABLE
(
    ID INT ,
    Name VARCHAR(500) ,
    Age INT 
)

INSERT INTO @table 
VALUES (1, 'Hello ## World! Test8.?##', 23), 
       (2, 'Need specific characters only Test8.? ]]', 22)

-- 指定有效字符:大小写字母、数字、问号
SELECT 
    ID,
    dbo.CleanInvalidChars(Name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?') AS CleanedName,
    Age
FROM @table;

进阶:结合配置表实现动态有效字符

如果有效字符需要频繁变动,可将其存入配置表,查询时动态读取,无需修改业务代码:

-- 创建配置表
CREATE TABLE ValidCharsConfig
(
    ConfigID INT PRIMARY KEY,
    ValidChars VARCHAR(100) NOT NULL
);

-- 插入有效字符配置
INSERT INTO ValidCharsConfig VALUES (1, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?');

-- 动态读取配置查询
SELECT 
    t.ID,
    dbo.CleanInvalidChars(t.Name, vc.ValidChars) AS CleanedName,
    t.Age
FROM @table t
CROSS JOIN ValidCharsConfig vc
WHERE vc.ConfigID = 1;

方案二:递归CTE(无需创建对象,临时查询适用)

如果不想创建函数,可使用递归CTE逐字符处理字符串,适合一次性临时查询场景:

DECLARE @table AS TABLE
(
    ID INT ,
    Name VARCHAR(500) ,
    Age INT 
)

INSERT INTO @table 
VALUES (1, 'Hello ## World! Test8.?##', 23), 
       (2, 'Need specific characters only Test8.? ]]', 22)

WITH RecursiveClean AS
(
    SELECT 
        ID,
        Name,
        Age,
        1 AS Position,
        CASE WHEN CHARINDEX(SUBSTRING(Name, 1, 1), 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?') > 0 
             THEN SUBSTRING(Name, 1, 1) 
             ELSE '' 
        END AS CleanedName
    FROM @table
    UNION ALL
    SELECT 
        ID,
        Name,
        Age,
        Position + 1,
        CleanedName + CASE WHEN CHARINDEX(SUBSTRING(Name, Position + 1, 1), 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?') > 0 
                           THEN SUBSTRING(Name, Position + 1, 1) 
                           ELSE '' 
                      END
    FROM RecursiveClean
    WHERE Position < LEN(Name)
)
SELECT 
    ID,
    MAX(CleanedName) AS CleanedName,
    Age
FROM RecursiveClean
GROUP BY ID, Age
OPTION (MAXRECURSION 0); -- 允许递归次数匹配字符串长度,设0表示无限制

方案说明

  • 函数方案适合长期复用,配合配置表可实现有效字符的动态调整,无需修改代码。
  • 递归CTE适合临时查询场景,无需创建数据库对象,但修改有效字符时需调整CTE内的字符集合。

内容的提问来源于stack exchange,提问作者Dev Learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 19:10:29