SQL 不同长度的 SUBSTRING 和 PATINDEX

SQL SUBSTRING & PATINDEX of varying lengths

SQL 服务器 2017.

给定以下 3 条记录,其字段类型为 nvarchar(250),称为 fileString

_318_CA_DCA_2020_12_11-01_00_01_VM6.log
_319_CA_DCA_2020_12_12-01_VM17.log
_333_KF_DCA01_00_01_VM232.log

我想 return:

VM6
VM17
VM232

到目前为止尝试过:

SELECT
SUBSTRING(fileString, PATINDEX('%VM[0-9]%', fileString), 3)      
FROM dbo.Table

但当然只有 return 个 VM 和 1 个号码。

当字符数变化时,我该如何定义参数?

编辑:先发制人地回答可能出现的问题,是的,VM 模式将始终由.log 立即进行,没有别的。但即使我采用这种方法并向后工作,我仍然不明白如何定义数字变化时要采用的字符数。

你的长度一开始是一致的。所以远离 patindex 并使用 substring 来裁剪开头。然后只需在末尾用空字符串替换'.log'即可。

select  *,
        part = replace(substring(filestring,33,255),'.log','')
from    table;

编辑:

好的,根据您的编辑,您显示了不同的前缀部分。那么 patindex 实际上是正确的。这是我的解决方案,它并不比其他答案好或坏,但不同之处在于它避免 reverse 并将 patindex 计算委托给交叉应用部分。您可能会发现它更具可读性。

select      filestring,
            part = replace(substring(filestring, ap.vmIx, 255),'.log','')
from        table
cross apply (select
                vmIx = patindex('%_vm%', filestring) + 1
            ) ap

这是一种方法:

DECLARE  @test TABLE( fileString varchar(500))

INSERT INTO @test VALUES 
 ('_318_CA_DCA_2020_12_11-01_00_01_VM6.log')
,('_319_CA_DCA_2020_12_12-01_00_01_VM17.log')
,('_333_KF_DCA_2020_12_15-01_00_01_VM232.log')


-- 5 is the length of file extension + 1 which is always the same size '.log'
SELECT
   REVERSE(SUBSTRING(REVERSE(fileString),5,CHARINDEX('_',REVERSE(fileString))-5))
FROM @test AS t

这将动态获取最后一个 _ 的长度和位置并删除 .log。

这不是最有效的,如果您能够使用 C# 编写一个 CLR 函数并将其导入到 SQL,那将更有效。或者您可以以此为起点并根据需要进行调整。

您可以删除变量并将其替换为您的 table,如下所示

DECLARE @TESTVariable as varchar(500)
Set @TESTVariable = '_318_CA_DCA_2020_12_11-01_00_01_VM6adf.log'

SELECT REPLACE(SUBSTRING(@TESTVariable, PATINDEX('%VM[0-9]%', @TESTVariable), PATINDEX('%[_]%', REVERSE(@TESTVariable))), '.log', '')

select  *,
        part = REPLACE(SUBSTRING(filestring, PATINDEX('%VM[0-9]%', filestring), PATINDEX('%[_]%', REVERSE(filestring))), '.log', '')
from    table