在SQL中拆分Varchar值

时间:2017-01-01 11:48:45

标签: sql-server tsql split

我在表格中有一列

表1

Tid.   name   fid
-----------------
 1.    Abc.   233
 2.    def.   344
 3.    xyz.   455

表2

did.   Status.   name                   FID
-------------------------------------------
 1      Open.        Abu,def,xyz            233,344,455

现在我想在这样的存储过程中将这些fid和name从table2中分离出来:

ID   status   name   FID
---------------
 1.   Open.     Abc.   233
 2.    Open.    Def.   344
 3    Open.     xyz.   455 

更新存储过程

查询:

Create procedure as splitdata 
As 
Begin 
   Declare @fid varchar (500) 

   Select name, select item as fid 
   from spiltstring(@fid,',')) 
   from table1 
   Inner join table2 on table1.fid = table2.fid

这显示错误

  

将varchar值'233,344,455'转换为数据类型int

时转换失败

在表1中,fidinttable2 fidvarchar类型。

分割字符串功能

CREATE FUNCTION SplitString
(    
      @Input NVARCHAR(MAX),
      @Character CHAR(1)
)
RETURNS @Output TABLE (Item NVARCHAR(1000))
AS
BEGIN
      DECLARE @StartIndex INT, @EndIndex INT

      SET @StartIndex = 1

      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)

            INSERT INTO @Output(Item)
            SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END
GO

我该怎么做?

更新

根据@john解决方案,我试试这个解决方案...

但是因为我有其他多个表

Create procedure as sp2
    @tick int
As
    Select
        Table 4.column, Table 5.column, Table 3.column,
        --so here I used solution like this
        (Select b.fid 
         from table2 t2 
         cross apply 
             (Select fid = s2.retval 
              from [udf-str-parase] (t2.fid, ',') s2) b),
        Table 6.column
    From 
        Table 2
    Inner join 
        table4 on table4.id = table5.id
    ..........
    Where 
        tick = @tick

当我尝试仅执行交叉应用查询时,这显示了完美的结果

但是当我尝试像这样执行整个存储过程时

Exec sp2 28

我收到此错误:

  

子查询返回的值超过1。这是不允许的。当子查询遵循=,!=,&lt; =,&gt; =,&gt;,&lt;或当子查询iI使用表达式时。

任何解决方案?

1 个答案:

答案 0 :(得分:1)

分组/解析功能和CROSS APPLY

的帮助
Declare @Table2 table (did int,Status varchar(50),name varchar(50),FID varchar(50))
Insert Into @Table2 values
(1,'Open.','Abu,def,xyz','233,344,455')


Select ID = Seq
      ,A.Status
      ,B.Name
      ,B.FID
 From  @Table2 A
 Cross Apply (
         Select Name=S1.RetVal
               ,FID =S2.RetVal
               ,Seq =S1.RetSeq
          From [dbo].[udf-Str-Parse](A.Name,',') S1
          Join [dbo].[udf-Str-Parse](A.FID,',')  S2
            on S1.RetSeq=S2.RetSeq
       ) B

返回

ID  Status  Name    FID
1   Open.   Abu     233
2   Open.   def     344
3   Open.   xyz     455

如果需要,拆分/解析UDF

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From  (Select x = Cast('<x>'+ replace((Select @String as [*] For XML Path('')),@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')