如何将不以逗号分隔的字符串的每个字符插入表中的单独行?

时间:2017-04-27 09:48:04

标签: sql-server sql-server-2008

我有一个像

这样的字符串
Declare @Str varchar (15) = '0123456789' 

我有一张桌子

CREATE TABLE TableNum(Nums Varchar(1));

如何将每个数字插入单独的行?

我的输出应该是

Nums
0
1
2
3
4
.
.

6 个答案:

答案 0 :(得分:1)

使用数字表可能是最好和最简单的方法。如果你没有alrady有一个数字表,你可以创建一个:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Tally
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Tally ADD CONSTRAINT PK_Tally PRIMARY KEY CLUSTERED (Number)

然后你所要做的只是这个:

INSERT INTO TableNum(Nums)
SELECT SUBSTRING(@Str, Number, 1)
FROM Tally
WHERE Number <= LEN(@Str)

有关您想要数字(或计数)表的原因的更多信息,请阅读Jeff Moden的this article

BTW,使用varchar(1)毫无意义 - 请改用char(1)

答案 1 :(得分:1)

试试这个:使用 CTE 可以实现这一点,无需对现有系统表使用任何连接

01-01-1970

答案 2 :(得分:1)

如果您无法添加计数表(,如Zohar Peled所示的方式),您可以使用临时高级表

Declare @Str varchar (15) = '0123456789' 

Select Num=substring(@Str,N,1)
 From (Select Top (Len(@Str)) N=Row_Number() Over (Order By (Select null)) From master..spt_values ) N

返回

Num
0
1
2
3
4
5
6
7
8
9

另一个选择是创建一个TVF

Declare @Str varchar (15) = '0123456789' 

Select * from [dbo].[udf-Str-Parse-Char](@Str) 

UDF

CREATE FUNCTION [dbo].[udf-Str-Parse-Char] (@String varchar(max))
Returns Table
As
Return (
    with   cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
           cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From cte1 a,cte1 b,cte1 c,cte1 d,cte1 e,cte1 f)

    Select RetSeq=N
          ,RetVal=Substring(@String,N,1) 
     From  cte2
) 
--Max 1 Million Observations
--Select * from [dbo].[udf-Str-Parse-Char]('this is a string') 

答案 3 :(得分:1)

试试这个

return (xxx,xxx);

然后

DECLARE @Str varchar(10) = '0123456789'
DECLARE @Count INT=1

WHILE @Count <= LEN(@Str)
BEGIN
    INSERT INTO TableNum
    SELECT substring(@Str, @count, 1)  
    SET @Count = @Count + 1
END

答案 4 :(得分:1)

Declare @Str varchar (15) = '0123456789' 
        ,@pos INT, 
         @result VARCHAR(100); 

   SET @result = @Str; 
   SET @pos = 2 -- location where we want first space 
   WHILE @pos < LEN(@result)+1 
   BEGIN 
       SET @result = STUFF(@result, @pos, 0, SPACE(1)); 
       SET @pos = @pos+2; 

  END
  SELECT @result=REPLACE( @result,' ',',')
  --Print @result
  SELECT   Split.a.value('.', 'VARCHAR(100)') AS Num  
        FROM  
        (
            SELECT   
                 CAST ('<M>' + REPLACE(@result, ',', '</M><M>') + '</M>' AS XML) AS Num  

        ) AS A CROSS APPLY Num.nodes ('/M') AS Split(a)

输出

Num
0
1
2
3
4
5
6
7
8
9

答案 5 :(得分:1)

试试这个。

CREATE TABLE TableNum(Nums Varchar(1));
TRUNCATE TABLE TableNum;

Declare @Str varchar (15) = '0123456789';

DECLARE @nLIMIT AS INT = LEN(@Str);
DECLARE @nCounter AS INT = 1;

WHILE @nCounter <= @nLIMIT
BEGIN  

   INSERT INTO TableNum VALUES(SUBSTRING (@Str,@nCounter,1));

   SET @nCounter = @nCounter + 1;
   IF @nCounter > @nLIMIT
         BREAK  
   ELSE  
      CONTINUE  
 END;

SELECT * FROM TableNum;