TSQL - 将分隔的字符串拆分为列

TSQL - Split delimited String into columns


问题

我有许多文件名字符串,我想使用波浪字符作为分隔符将其解析为列。字符串采用静态格式:

因此,完整的串联示例如下:

C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf

我想忽略字符串中给出的文件路径和扩展名,只将以下值解析到列中:

所以像这样:

SELECT Surname = --delimitedString[0]
       FirstName = --delimitedString[1]
       --etc.

我试过的

我知道我需要执行几项任务才能拆分字符串,首先我需要 trim 关闭扩展名和文件路径,以便我可以 return由波浪线 (~) 分隔的字符串。

这对我来说是第一个问题,但是问题 2 是拆分新的分隔字符串本身,即

Walker~Thomas~19991226~20180416150322

我已经很好地阅读了这篇非常全面的 question 并且似乎(因为我使用 SQL Server 2008R2)唯一的选择是使用带循环的函数或递归 CTE 或尝试使用 SUBSTRING()charIndex().

的非常混乱的尝试

我知道如果我可以访问 SQL Server 2016,我可以使用 string_split 但不幸的是我无法升级。

我确实可以访问 SSIS,但我对它还很陌生,所以决定尝试在 SQL 语句

中完成大部分工作

我知道你提到过想尽可能避免使用 charindex() 选项,但我以一种半可读的方式解决了这个问题。当我 space 每个参数在不同的行上并使用缩进级别时,我发现像这样阅读复杂的函数有点容易。这不是最合适的外观,但它有助于提高易读性:

with string as (select 'C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf' as filepath)

select 
    substring(
        filepath,
        len(filepath)-charindex('\',reverse(filepath))+2,           --start location, after last '\'
        len(filepath)-                                              --length of path
            (len(filepath)-charindex('\',reverse(filepath))+2)-         --less characters up to last '\'
            (len(filepath)-charindex('.',filepath))                     --less file extention
        )
from string

这里有一个没有分离器的方法应该不会太复杂...

declare @var table (filepath varchar(256))
insert into @var values
('C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf')


;with string as(
select 
    x = right(filepath,charindex('\',reverse(filepath))-1) 
    from @var
)

select
    SurName= substring(x,1,charindex('~',x) - 1)
    ,FirstName = substring(x,charindex('~',x) + 1,charindex('~',x) - 1)
from string

Fritz 已经有了一个很好的开始,我的回答只是补充一下

with string as (select 'C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf' as filepath)
, newstr as (
select 
    REPLACE(substring(
        filepath,
        len(filepath)-charindex('\',reverse(filepath))+2,           --start location, after last '\'
        len(filepath)-                                              --length of path
            (len(filepath)-charindex('\',reverse(filepath))+2)-         --less characters up to last '\'
            (len(filepath)-charindex('.',filepath))                     --less file extention
        ) , '~', '.') as new_part
from string
)
SELECT
      PARSENAME(new_part,4) as Surname,
      PARSENAME(new_part,3) as [First Name],
      PARSENAME(new_part,2) as [Birth Date], 
      PARSENAME(new_part,1) as [Document Created Datetime]
FROM newstr