SQL Server中如何根据指定模式提取对应的目标子字符串
SQL Server 从变更日志字符串中提取更新后字段值的方案
待处理字符串格式:FirstName changed from (Joe) to (Sally), LastName changed from (Doe) to (Harris)
首先澄清一个误区:SUBSTRING 本身可以处理变长内容,只需要搭配定位函数锁定目标子串的起止位置即可,也可以根据你使用的SQL Server版本选择更简便的实现方案:
方案一:全版本兼容方案(CHARINDEX + SUBSTRING)
适用于所有SQL Server版本,无需依赖高级函数,只要字符串符合[字段名] changed from (旧值) to (新值)的固定规则即可使用:
DECLARE @ChangeStr NVARCHAR(200) = 'FirstName changed from (Joe) to (Sally), LastName changed from (Doe) to (Harris)' -- 提取更新后的FirstName DECLARE @To_FirstName_Pos INT = CHARINDEX('to (', @ChangeStr) + 4 -- 跳过"to ("共4个字符定位到新值首字符 DECLARE @End_FirstName_Pos INT = CHARINDEX(')', @ChangeStr, @To_FirstName_Pos) -- 定位新值后的右括号位置 DECLARE @NewFirstName NVARCHAR(50) = SUBSTRING(@ChangeStr, @To_FirstName_Pos, @End_FirstName_Pos - @To_FirstName_Pos) -- 提取更新后的LastName DECLARE @To_LastName_Pos INT = CHARINDEX('to (', @ChangeStr, @End_FirstName_Pos) +4 DECLARE @End_LastName_Pos INT = CHARINDEX(')', @ChangeStr, @To_LastName_Pos) DECLARE @NewLastName NVARCHAR(50) = SUBSTRING(@ChangeStr, @To_LastName_Pos, @End_LastName_Pos - @To_LastName_Pos) -- 输出结果 SELECT @NewFirstName AS NewFirstName, @NewLastName AS NewLastName
方案二:SQL Server 2022及以上版本正则简化方案
如果使用SQL Server 2022或更高版本,可以直接调用内置的REGEXP_SUBSTR正则函数简化逻辑:
DECLARE @ChangeStr NVARCHAR(200) = 'FirstName changed from (Joe) to (Sally), LastName changed from (Doe) to (Harris)' SELECT REGEXP_SUBSTR(@ChangeStr, 'FirstName changed from \([^)]+\) to \(([^)]+)\)', 1, 1, NULL, 1) AS NewFirstName, REGEXP_SUBSTR(@ChangeStr, 'LastName changed from \([^)]+\) to \(([^)]+)\)', 1, 1, NULL, 1) AS NewLastName
正则逻辑说明:通过捕获组提取to (之后、最近的)之前的内容,最后一位参数1代表直接返回第一个捕获组的匹配结果。
内容的提问来源于stack exchange,提问作者Ramon Gallo
相关产品推荐
相关产品推荐

