2011-06-10 65 views
7

我在MSSQL这个很长的字符串,我需要我的价值。解析字符串SQL

I代表发票, A表示金额, d表示日期

I = 940; A = 29.5; d = 20090901 | I = 941; A = 62.54; d = 20090910 | I = 942 ; A = 58.99; d = 20091005 | I = 954; A = 93.45; d = 20091201 | I = 944; A = 96.76; d = 20091101 | I = 946; A = 52.5; d = 20091101 | I = 943; A = 28.32; d = 20091101 | I = 945; A = 52.5; d = 20091101 | I = 955; A = 79.81; d = 20091201 | I = 950; A = 25.2; d = 20091124 | I = 948; A = 31.86 ; d = 20091110 | I = 949; A = 28.32; d = 20091120 | I = 947; A = 25.2; d = 20091109 | I = 951; A = 242.54; d = 20091124 | I = 952; A = 28.32; d = 20091129 | I = 956; A = 38.94; d = 20091210 | I = 957; A = 107.39; d = 20091215 | I = 958; A = 32.55; d = 20091228 | I = 959; A = 27.3; d = 20091228 | I = 960; A = 24.79; d = 20091230 | I = 1117; A = 28.32; d = 20100131 | I = 1115; A = 272.58; d = 20100131 | I = 1116; A = 159.6; d = 20100209

这是最可怕的案件之一。

每这些都是有我将使用链接到另一个事务相关的值发票号。我真的很感激,如果有人可以解释去了解这一点的最好方式未做如果可能的话

+4

如果可能的话,在应用程序中解析它并将数据传递给SQL。 – Oded 2011-06-10 14:22:44

+1

我不清楚你在问什么。这个字符串是一个变量中的值,并且您正在从中提取某些值?通过给出的示例输入,你能举出一个你想要制作的例子吗? – StriplingWarrior 2011-06-10 14:24:08

+0

这是说的是在MSSQL其由圣人柔和的进化产生与支付问候,并再次,我需要每一个我很看重我希望这清除了问题 – Enzero 2011-06-10 14:27:06

回答

28
declare @s varchar(max) = 'I=940;A=29.5;D=20090901|I=941;A=62.54;D=20090910|I=942;A=58.99;D=20091005|I=954;A=93.45;D=20091201|I=944;A=96.76;D=20091101|I=946;A=52.5;D=20091101|I=943;A=28.32;D=20091101|I=945;A=52.5;D=20091101|I=955;A=79.81;D=20091201|I=950;A=25.2;D=20091124|I=948;A=31.86;D=20091110|I=949;A=28.32;D=20091120|I=947;A=25.2;D=20091109|I=951;A=242.54;D=20091124|I=952;A=28.32;D=20091129|I=956;A=38.94;D=20091210|I=957;A=107.39;D=20091215|I=958;A=32.55;D=20091228|I=959;A=27.3;D=20091228|I=960;A=24.79;D=20091230|I=1117;A=28.32;D=20100131|I=1115;A=272.58;D=20100131|I=1116;A=159.6;D=20100209' 
declare @xml xml 

select @xml = '<item><value>'+replace(replace(@s, ';','</value><value>'), '|','</value></item><item><value>')+'</value></item>' 

select N.value('substring(value[1],3)', 'int') as Invoice, 
     N.value('substring(value[2],3)', 'money') as Amount, 
     N.value('substring(value[3],3)', 'date') as [Date] 
from @xml.nodes('item') as T(N) 

结果:

Invoice  Amount    Date 
----------- --------------------- ---------- 
940   29,50     2009-09-01 
941   62,54     2009-09-10 
942   58,99     2009-10-05 
954   93,45     2009-12-01 
944   96,76     2009-11-01 
946   52,50     2009-11-01 
943   28,32     2009-11-01 
945   52,50     2009-11-01 
955   79,81     2009-12-01 
950   25,20     2009-11-24 
948   31,86     2009-11-10 
949   28,32     2009-11-20 
947   25,20     2009-11-09 
951   242,54    2009-11-24 
952   28,32     2009-11-29 
956   38,94     2009-12-10 
957   107,39    2009-12-15 
958   32,55     2009-12-28 
959   27,30     2009-12-28 
960   24,79     2009-12-30 
1117  28,32     2010-01-31 
1115  272,58    2010-01-31 
1116  159,60    2010-02-09 

对于SQL Server 2005,您需要使用日期时间,而不是日期

select N.value('substring(value[1],3)', 'int') as Invoice, 
     N.value('substring(value[2],3)', 'money') as Amount, 
     N.value('substring(value[3],3)', 'datetime') as [Date] 
from @xml.nodes('item') as T(N) 

要从你需要做这样的一个表中读取。

declare @s varchar(max) = 'I=940;A=29.5;D=20090901|I=941;A=62.54;D=20090910|I=942;A=58.99;D=20091005|I=954;A=93.45;D=20091201|I=944;A=96.76;D=20091101|I=946;A=52.5;D=20091101|I=943;A=28.32;D=20091101|I=945;A=52.5;D=20091101|I=955;A=79.81;D=20091201|I=950;A=25.2;D=20091124|I=948;A=31.86;D=20091110|I=949;A=28.32;D=20091120|I=947;A=25.2;D=20091109|I=951;A=242.54;D=20091124|I=952;A=28.32;D=20091129|I=956;A=38.94;D=20091210|I=957;A=107.39;D=20091215|I=958;A=32.55;D=20091228|I=959;A=27.3;D=20091228|I=960;A=24.79;D=20091230|I=1117;A=28.32;D=20100131|I=1115;A=272.58;D=20100131|I=1116;A=159.6;D=20100209' 

declare @YourTable table(ID int, s varchar(max)) 
insert into @YourTable values 
(1, @s), 
(2, @s) 

select Y.ID, 
     T.N.value('substring(value[1],3)', 'int') as Invoice, 
     T.N.value('substring(value[2],3)', 'money') as Amount, 
     T.N.value('substring(value[3],3)', 'date') as [Date] 
from @YourTable as Y 
    cross apply (select cast('<item><value>'+replace(replace(Y.s, ';','</value><value>'), '|','</value></item><item><value>')+'</value></item>' as xml)) as X(XMLCol) 
    cross apply X.XMLCol.nodes('item') as T(N) 
+2

真棒答案! – JosephStyons 2011-06-10 15:00:53

+0

Thx只需将它连接到字段然后dbo.PostAP.cAllocs它应该工作正确? – Enzero 2011-06-10 15:08:52

+0

@Enzero - 不知道。什么是dbo.PostAP.cAllocs?你想在那里保存输出吗? – 2011-06-10 15:12:18

0

不知道这是否会帮助你的应用程序,但这里是一个SQL服务器兼容的字符串分析器功能... 这样称呼它:

Select * From dbo.ParseTextString([Your long text string here], '|') 

的功能是:

Create FUNCTION [dbo].[ParseTextString] (@S Text, @delim VarChar(5)) 
Returns @tOut Table 
(ValNum Integer Identity Primary Key, 
sVal VarChar(8000)) 
As 
Begin 
Declare @dLLen TinyInt  -- Length of delimiter 
Declare @sWin VarChar(8000)-- Will Contain Window into text string 
Declare @wLen Integer  -- Length of Window 
Declare @wLast TinyInt  -- Boolean to indicate processing Last Window 
Declare @wPos Integer  -- Start Position of Window within Text String 
Declare @sVal VarChar(8000)-- String Data to insert into output Table 
Declare @BtchSiz Integer -- Maximum Size of Window 
Set @BtchSiz = 7900  -- (Reset to smaller values to test routine) 
Declare @dPos Integer  -- Position within Window of next Delimiter 
Declare @Strt Integer  -- Start Position of each data value within Window 
-- ------------------------------------------------------------------------- 

-- --------------------------- 
If @delim is Null Set @delim = '|' 
If DataLength(@S) = 0 Or 
    Substring(@S, 1, @BtchSiz) = @delim Return 
-- --------------------------- 
Select @dLLen = Len(@delim), 
    @Strt = 1, @wPos = 1, 
    @sWin = Substring(@S, 1, @BtchSiz) 
Select @wLen = Len(@sWin), 
     @wLast = Case When Len(@sWin) = @BtchSiz 
       Then 0 Else 1 End, 
     @dPos = CharIndex(@delim, @sWin, @Strt) 
-- ---------------------------- 
While @Strt <= @wLen 
    Begin 
    If @dPos = 0 Begin -- No More delimiters in window 
     If @wLast = 1 Set @dPos = @wLen + 1 
     Else Begin 
     Set @wPos = @wPos + @Strt - 1 
     Set @sWin = Substring(@S, @wPos, @BtchSiz) 
     -- ---------------------------------------- 
     Select @wLen = Len(@sWin), @Strt = 1, 
       @wLast = Case When Len(@sWin) = @BtchSiz 
        Then 0 Else 1 End, 
       @dPos = CharIndex(@delim, @sWin, 1) 
       If @dPos = 0 Set @dPos = @wLen + 1 
      End 
     End 
     -- ------------------------------- 
     Set @sVal = LTrim(Substring(@sWin, @Strt, @dPos - @Strt)) 
     Insert @tOut (sVal) Values (@sVal) 
     -- ------------------------------- 
     -- Move @Strt to char after last delimiter 
     Set @Strt = @dPos + @dLLen 
     Set @dPos = CharIndex(@delim, @sWin, @Strt) 
    End 
    Return 
    End 
0

我使用的功能在SQL分割字符串,也许这可能是你的出发点:

CREATE Function [dbo].[CsvToVarchar] (@Array varchar(4000)) 
returns @IntTable table 
    (CharsValue VARCHAR(40)) 
AS 
begin 

    declare @separator varchar(5) 
    set @separator = ',' 

    declare @separator_position int 
    declare @array_value varchar(4000) 

    set @array = @array + @separator 

    while patindex('%'[email protected]+'%' , @array) <> 0 
    begin 

     select @separator_position = patindex('%'[email protected]+'%' , @array) 
     select @array_value = left(@array, @separator_position - 1) 

     Insert @IntTable 
     Values (@array_value) 

     select @array = stuff(@array, 1, @separator_position, '') 
    end 

    return 
end