2017-01-17 2 views
1

Ich arbeite mit einigen ungeraden Strings und versuche sie zu parsen.SQL String - Manipulation und Parsing

Beispiel: ALS KICKBACK:AK:Acts1:SCErrors1:FErrors0:Overlays0

Das Endergebnis wird erwartet, wie hier gezeigt:

enter image description here

Ich habe zusammengeschustert, einige Codes, aber ich bin nicht sicher, dass es in allen Szenarien arbeiten. Irgendwelche Vorschläge würden geschätzt werden.

CASE WHEN [Short Description] Like 'ALS KICKBACK:%:Acts%' THEN Left(SubString([Short Description], PatIndex('%[0-9.-]%', [Short Description]), 8000), 
    PatIndex('%[^0-9.-]%', SubString([Short Description], PatIndex('%[0-9.-]%', [Short Description]), 8000) + 'X')-1) 
WHEN [Short Description] Like 'ALS:KICKBACK:%:Acts%' THEN Left(SubString([Short Description], PatIndex('%[0-9.-]%', [Short Description]), 8000), 
    PatIndex('%[^0-9.-]%', SubString([Short Description], PatIndex('%[0-9.-]%', [Short Description]), 8000) + 'X')-1)  
    ELSE '0'END as Acts 

Danke.

+0

ich die Sprache der Mangel an Ausdruckskraft und die starren reinen funktionalen Stil es Mandate wegen nichts über triviale String-Operationen in SQL empfehlen , ohne sogar Zwischenvariablen (was zu wiederholten 'CHARINDEX'-Aufrufen führt). Gibt es einen Grund, warum Sie diese Verarbeitung nicht im Client-Code durchführen können? – Dai

+1

Auch welche DBMS benutzen Sie? Es sieht wie MS SQL Server aus - wenn dies der Fall ist, können Sie Ihren Code vereinfachen, indem Sie eine skalare UDF und/oder die eingebettete .NET-Laufzeitumgebung (SQL CLR) anstelle von T-SQL verwenden. – Dai

+0

Welches DBMS benutzen Sie? Das ist in Postgres ziemlich einfach. –

Antwort

1

Ein Verfahren ist mit einem Kreuz anwenden und Parse Funktion

Option 1: Mit einem Parse Funktion

Declare @YourTable table (ID int,[Short Description] varchar(max)) 
Insert Into @YourTable values 
(1,'ALS KICKBACK:AK:Acts1:SCErrors1:FErrors0:Overlays0') 

Select A.ID 
     ,[Short Description] 
     ,B.* 
From @YourTable A 
Cross Apply (
       Select Acts  = max(case when PatIndex('Acts[0-9]%' ,RetVal)>0 then replace(RetVal,'Acts' ,'') end) 
        ,SCErrors = max(case when PatIndex('SCErrors[0-9]%',RetVal)>0 then replace(RetVal,'SCErrors','') end) 
        ,FErrors = max(case when PatIndex('FErrors[0-9]%' ,RetVal)>0 then replace(RetVal,'FErrors' ,'') end) 
        ,Overlays = max(case when PatIndex('Overlays[0-9]%',RetVal)>0 then replace(RetVal,'Overlays','') end) 
       From [dbo].[udf-Str-Parse](A.[Short Description],':') 
     ) B 

Option 2: ohne eine Funktion

Declare @YourTable table (ID int,[Short Description] varchar(max)) 
Insert Into @YourTable values 
(1,'ALS KICKBACK:AK:Acts1:SCErrors1:FErrors0:Overlays0') 

Select A.ID 
     ,[Short Description] 
     ,B.* 
From @YourTable A 
Cross Apply (
       Select Acts  = max(case when PatIndex('Acts[0-9]%' ,RetVal)>0 then replace(RetVal,'Acts' ,'') end) 
        ,SCErrors = max(case when PatIndex('SCErrors[0-9]%',RetVal)>0 then replace(RetVal,'SCErrors','') end) 
        ,FErrors = max(case when PatIndex('FErrors[0-9]%' ,RetVal)>0 then replace(RetVal,'FErrors' ,'') end) 
        ,Overlays = max(case when PatIndex('Overlays[0-9]%',RetVal)>0 then replace(RetVal,'Overlays','') end) 
       From (
         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 [Short Description] as [*] For XML Path('')),':','</x><x>')+'</x>' as xml).query('.')) as A 
         Cross Apply x.nodes('x') AS B(i) 
        ) P 
     ) B 

Beide Optionen Zurück

enter image description here


Die UDF bei Bedarf

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(25)) 
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 (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A), 
      cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter)) = @Delimiter), 
      cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter,@String,s.N),0)-S.N,8000) From cte3 S) 

    Select RetSeq = Row_Number() over (Order By A.N) 
      ,RetVal = LTrim(RTrim(Substring(@String, A.N, A.L))) 
    From cte4 A 
); 
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/ 
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||') 
+0

@ChrisW Glücklich es geholfen –

+0

Schöne John Cappelletti. Ich danke dir sehr. Ich dachte nicht daran, eine Funktion für einen Teil davon zu verwenden. Extrem hilfreich. – ChrisW