如何在T-SQL中指定正则/LIKE匹配字符数?Teradata转SQL Server
将Teradata REGEXP_SUBSTR转换为SQL Server 2016 T-SQL
核心限制说明
SQL Server 2016不支持原生正则表达式量词(如{2}、{3}),也没有REGEXP_SUBSTR这类正则提取函数,只能通过LIKE或PATINDEX结合SUBSTRING实现需求。
1. 匹配格式的WHERE条件
针对你需要的XX-99-999(-XX)?格式(最后两位字母可选),可以用以下两种方式:
方式一:LIKE语句
WHERE CONTRACT_PD_AOR LIKE '[a-zA-Z][a-zA-Z]-[0-9][0-9]-[0-9][0-9][0-9]%' AND (LEN(CONTRACT_PD_AOR) = 10 OR (LEN(CONTRACT_PD_AOR) >=13 AND CONTRACT_PD_AOR LIKE '%-[a-zA-Z][a-zA-Z]%'))
方式二:PATINDEX语句
WHERE PATINDEX('[a-zA-Z][a-zA-Z]-[0-9][0-9]-[0-9][0-9][0-9]%', CONTRACT_PD_AOR) > 0 OR PATINDEX('[a-zA-Z][a-zA-Z]-[0-9][0-9]-[0-9][0-9][0-9]-[a-zA-Z][a-zA-Z]%', CONTRACT_PD_AOR) > 0
2. 提取匹配的合同号(模拟REGEXP_SUBSTR)
如果需要提取字符串中第一个符合格式的合同号,可结合PATINDEX和SUBSTRING实现:
SELECT CASE -- 匹配带后缀字母的格式(XX-99-999-XX) WHEN PATINDEX('%[a-zA-Z][a-zA-Z]-[0-9][0-9]-[0-9][0-9][0-9]-[a-zA-Z][a-zA-Z]%', CONTRACT_PD_AOR) > 0 THEN SUBSTRING( CONTRACT_PD_AOR, PATINDEX('%[a-zA-Z][a-zA-Z]-[0-9][0-9]-[0-9][0-9][0-9]-[a-zA-Z][a-zA-Z]%', CONTRACT_PD_AOR), 13 -- 固定长度:2+1+2+1+3+1+2=13 ) -- 匹配不带后缀字母的格式(XX-99-999) WHEN PATINDEX('%[a-zA-Z][a-zA-Z]-[0-9][0-9]-[0-9][0-9][0-9]%', CONTRACT_PD_AOR) > 0 THEN SUBSTRING( CONTRACT_PD_AOR, PATINDEX('%[a-zA-Z][a-zA-Z]-[0-9][0-9]-[0-9][0-9][0-9]%', CONTRACT_PD_AOR), 10 -- 固定长度:2+1+2+1+3=10 ) ELSE NULL END AS MATCHED_CONTRACT_NO FROM cn
更简便的替代方案
如果可以升级到SQL Server 2017及以上版本,就能直接使用原生正则函数,写法和Teradata几乎一致:
SELECT REGEXP_SUBSTR(cn.CONTRACT_PD_AOR, '\b([a-zA-Z]{2})-([0-9]{2})-([0-9]{3})(-([a-zA-Z]{2}))?\b') AS MATCHED_CONTRACT_NO FROM cn
内容的提问来源于stack exchange,提问作者WannabeDev
相关产品推荐
相关产品推荐

