如何使用T-SQL使用分隔符字符拆分字符串?

28 浏览
0 Comments

如何使用T-SQL使用分隔符字符拆分字符串?

表的其中一列中有一个很长的字符串。我只想获取特定的信息:-

我的表结构:-

Col1 = '123'
Col2 = 'AAAAA'
Col3 = 'Clent ID = 4356hy|Client Name = B B BOB|Client Phone = 667-444-2626|Client Fax = 666-666-0151|Info = INF8888877 -MAC333330554/444400800'

我的选择语句是:-

从Table01选择col1,col2,col3

但是在Col3中,我只需要'Client Name'的值,即'B B BOB'。

在Col3中 -

  • 列分隔符是'|'(例如'Client ID = 4356hy')
  • 键值分隔符是' = '(等号前后各有一个空格)。

请帮忙。

0
0 Comments

问题的原因是在使用T-SQL时,需要将字符串按照特定的分隔符进行拆分。这个问题的解决方法是使用以下的T-SQL代码:

Select col1, col2, LTRIM(RTRIM(SUBSTRING(
    STUFF(col3, CHARINDEX('|', col3,
    PATINDEX('%|Client Name =%', col3) + 14), 1000, ''),
    PATINDEX('%|Client Name =%', col3) + 14, 1000))) col3
from Table01

在解决这个问题的过程中,作者还进行了CharIndex和PatIndex的比较测试,测试结果显示,在进行了700k次调用时,两者的执行时间相差不到3.5%,因此作者认为无论使用哪种方法都不会有太大差异,可以根据具体情况选择使用。

作者还提出了一个疑问,即`PATINDEX('%|Client Name =%', col3)`和`CHARINDEX('|Client Name =', col3)`是否相同,并且后者是否比前者更快。

0
0 Comments

问题出现的原因是数据库设计不合理。解决方法是使用T-SQL中的SUBSTR函数和REPLACE函数来拆分字符串。

下面是一个使用SUBSTR和REPLACE函数来拆分字符串的示例代码:

Select col1, col2, REPLACE(substr(col3, instr(col3, 'Client Name'), 
    (instr(col3, '|', instr(col3, 'Client Name')  -
    instr(col3, 'Client Name'))
    ),
'Client Name = ',
'')
from Table01 

这段代码中,首先使用SUBSTR函数找到字符串中"Client Name"的位置,并使用INSTR函数找到该位置后的第一个竖线"|"的位置。然后使用INSTR函数找到"Client Name"的位置,并将这两个位置相减,得到子字符串的长度。最后使用SUBSTR函数截取子字符串,并使用REPLACE函数将"Client Name = "替换为空字符串。

总之,通过使用SUBSTR和REPLACE函数,我们可以在T-SQL中简单地按照分隔符字符拆分字符串。然而,需要注意的是,这种数据库设计是不合理的,因为它使得查询操作变得复杂和低效。对于更好的数据库设计,应该将相关的数据分割成不同的列或使用关联表来存储。

0
0 Comments

在T-SQL中,有时候我们需要根据特定的分隔符将字符串拆分为多个部分。然而,T-SQL并没有内置的函数来实现这个功能。因此,我们需要创建一个自定义的函数来完成这个任务。

下面是一个用于拆分字符串的函数示例:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[udf_Split]
(   
    @String nvarchar(max),
    @Delimiter nvarchar(2) = ','
)
RETURNS TABLE 
AS
RETURN 
(
    WITH CorrectedList AS
    (
        SELECT 
            CASE WHEN LEFT(@String, LEN(@Delimiter)) <> @Delimiter THEN '' ELSE '' END
            + @String +
            CASE WHEN RIGHT(@String, LEN(@Delimiter)) <> @Delimiter THEN '' ELSE '' END AS List,
            LEN(@Delimiter) AS DelimiterLen
    ),
    Numbers AS 
    (
        SELECT TOP (COALESCE(DATALENGTH(@String) / 2, 0)) 
            ROW_NUMBER() OVER(ORDER BY c1.object_id) AS Value
        FROM sys.columns AS c1
        CROSS JOIN sys.columns AS c2
    )
    SELECT 
        CHARINDEX(@Delimiter, CL.List, N.Value) + CL.DelimiterLen AS Position,
        SUBSTRING(
            CL.List,
            CHARINDEX(@Delimiter, CL.List, N.Value) + CL.DelimiterLen,
            CHARINDEX(@Delimiter, CL.List, N.Value + 1) - (CHARINDEX(@Delimiter, CL.List, N.Value) + CL.DelimiterLen)
        ) AS Value
    FROM CorrectedList AS CL
    CROSS JOIN Numbers AS N
    WHERE N.Value <= DATALENGTH(CL.List) / 2
    AND SUBSTRING(CL.List, N.Value, CL.DelimiterLen) = @Delimiter
)

使用上述函数,我们可以使用Cross Apply来获取拆分后的数据:

SELECT 
    T.Col1, 
    T.Col2,
    SUBSTRING(Z.Value, 1, CHARINDEX(' = ', Z.Value) - 1) AS AttributeName,
    SUBSTRING(Z.Value, CHARINDEX(' = ', Z.Value) + 1, LEN(Z.Value)) AS Value
FROM Table01 AS T
CROSS APPLY dbo.udf_Split(T.Col3, '|') AS Z

然而,这个函数并不总是能给出一致的结果。有一些问题被提出,包括一个问题演示了这个问题。更多详情请参考stackoverflow.com/q/12480321

0