我该如何编写这个T-SQL游标?

时间:2013-09-26 06:04:17

标签: sql-server tsql cursor

我在表格的一个单元格中有多个值,这些值由一个空格相互隔开。这是我的表格的样子,每个单元格中每个字符串之间都有一个空格:

column1 | column2
        |
abc fgt | rty lkj

我想基于第一个表创建另一个表,其中“abc”和“rty”在一行中,因为它们都位于第一位,“fgt”和“lkj”位于另一行中相同的关系原因(他们排在第二位等等):

column1 | column2
        |
abc     | rty
fgt     | lkj

我该怎么做?

2 个答案:

答案 0 :(得分:1)

您可以使用这样的功能

IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID('UF_CSVToTable'))
 DROP FUNCTION UF_CSVToTable
GO

CREATE FUNCTION UF_CSVToTable
(
 @psCSString VARCHAR(8000)
)
RETURNS @otTemp TABLE(sID VARCHAR(20),tID VARCHAR(20))
AS
BEGIN
 DECLARE @sTemp VARCHAR(10)
 DECLARE @tTemp VARCHAR(10)

 WHILE LEN(@psCSString) > 0
 BEGIN
  SET @sTemp = LEFT(@psCSString, ISNULL(NULLIF(CHARINDEX(' ', @psCSString) - 1, -1),
                    LEN(@psCSString)))
  SET @psCSString = SUBSTRING(@psCSString,ISNULL(NULLIF(CHARINDEX(' ', @psCSString), 0),
                               LEN(@psCSString)) + 1, LEN(@psCSString))
  INSERT INTO @otTemp(sID) VALUES (@sTemp)

  SET @tTemp = LEFT(@psCSString, ISNULL(NULLIF(CHARINDEX(' ', @psCSString) - 1, -1),
                    LEN(@psCSString)))
  SET @psCSString = SUBSTRING(@psCSString,ISNULL(NULLIF(CHARINDEX(' ', @psCSString), 0),
                               LEN(@psCSString)) + 1, LEN(@psCSString))
  UPDATE @otTemp SET tID=@tTemp WHERE sID=@sTemp                        
 END

RETURN
END
Go

可以像这样调用。

select * from UF_CSVToTable('1 2 3 4 5 6 7 15 55 59 86')

您需要将列作为输入参数传递。

SQL FIDDLE DEMO

答案 1 :(得分:0)

首先,您可以创建UDF以按特定分隔符分割值(在您的情况下,这是SPACE):

CREATE FUNCTION [dbo].[Split](@String nvarchar(4000), @Delimiter char(1))       
returns @temptable TABLE (rownumber INT , items nvarchar(4000))       
as       
begin       
    declare @idx int       
    declare @slice nvarchar(4000) 
    DECLARE @rownumber int = 1     

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)       
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(rownumber, Items) values(@rownumber, @slice)       

        set @String = right(@String,len(@String) - @idx) 
        SET @rownumber = @rownumber + 1      
        if len(@String) = 0 break       
    end   
return       
end  
GO

之后,编写简单的INSERT INTO SELECT...查询就足够了:

INSERT INTO dbo.Table_2
        ( column1, column2 )
SELECT 
    item1.items ,
    item2.items
FROM dbo.Split((SELECT column1 FROM dbo.Table_1), SPACE(1)) AS item1 
    FULL JOIN dbo.Split((SELECT column2 FROM dbo.Table_1), SPACE(1)) AS item2 
        ON item1.rownumber = item2.rownumber

Table_1是实际值为的表,Table_2是最终行的表。

SQL Fiddle Demo