在不使用WHILE循环的情况下在T-SQL中拆分可变长度列

时间:2013-12-23 21:26:20

标签: string sql-server-2008 tsql

我在表格中有一列数据,其长度各不相同。对于某些记录,列的长度是8,对于某些记录,它是20,对于许多记录,它是介于两者之间的一些数字,而不是必须被4整除。

我被要求将此数据更改为xxxx.xxxx.xxxx.等,直到我的数字用完为止。所以,例如,如果我有

12345678

我应该把它改成

1234.5678. 
  • 如果我有12345,我应该将其更改为1234.5
  • 1234567890ABCDEFGH变为1234.5678.90AB.CDEF.GH

我可以使用WHILE循环执行此操作,但我尝试远离T-SQL中的循环并使用set逻辑。我想知道,有没有办法做到这一点,不涉及循环?

3 个答案:

答案 0 :(得分:1)

我不清楚是否/何时包括最后一段时间,但以下似乎可以做你想要的:

select ((case when len(val) > 0 then substring(val, 1, 4) + '.' else '' end) +
        (case when len(val) > 4 then substring(val, 5, 4) + '.' else '' end) +
        (case when len(val) > 8 then substring(val, 9, 4) + '.' else '' end) +
        (case when len(val) > 12 then substring(val, 13, 4) + '.' else '' end) +
        (case when len(val) > 16 then substring(val, 17, 4) else '' end) 
       )

答案 1 :(得分:1)

DECLARE @val varchar(20) = '12345678'

SELECT RTRIM(COALESCE(
        STUFF(STUFF(STUFF(STUFF(@val+' ',5,0,'.'),10,0,'.'),15,0,'.'),20,0,'.'),
        STUFF(STUFF(STUFF(@val+' ',5,0,'.'),10,0,'.'),15,0,'.'),
        STUFF(STUFF(@val+' ',5,0,'.'),10,0,'.'),
        STUFF(@val+' ',5,0,'.'),
        @val
        ))

答案 2 :(得分:0)

您可以使用数字表来避免对大量字符串长度为50的情况进行硬编码。

DECLARE @Nums TABLE(N INT PRIMARY KEY);

INSERT INTO @Nums VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13)

UPDATE YourTable
SET    Val = STUFF((SELECT '.' + SUBSTRING(Val, N * 4 + 1, 4)
                    FROM   @Nums
                    WHERE  N <= ( LEN(Val) - 1 ) / 4
                    ORDER BY N
                    FOR XML PATH('')), 1, 1, '') 

SQL Fiddle