2017-06-03 9 views
0

In SQL Server 2014, wie regulären Ausdruck Funktion umschreiben, um unterhalb der Ausgabe zu erreichen?SQL Server 2014 extrahieren Zeichenfolge

ABB_FET_abb_98693989-121966_20170304052411709.csv 

ERP ID = 98693989 
CATALOG ID = 98693989-121966 

In regex kann ich unten Muster verwenden ERP ID und Catalog id zu erhalten, aber, wie diese in SQL Server zu tun?

^.*?_.*?_.*?_(.*?)-(\w+) 
^.*?_.*?_.*?_(.*?)_(\w+) 
+1

Mögliche Duplikat [SQL Server reguläre Ausdrücke] (https: // Stackoverflow. com/fragen/5212665 ​​/ sql-server-regular-ausdrücken) –

Antwort

0

Sie könnten folgende Lösung versuchen:

DECLARE @Source VARCHAR(100) = 'ABB_FET_abb_98693989-121966_20170304052411709.csv' 

SELECT * 
FROM (VALUES (CONVERT(XML, N'<root><i>' + REPLACE(@Source, N'_', N'</i><i>') + N'</i></root>'))) AS x(XmlCol) 
CROSS APPLY (
    SELECT x.XmlCol.value('(root/i)[4]', 'VARCHAR(25)') 
) AS y(CATALOG_ID) 
CROSS APPLY (
    SELECT LEFT(y.Catalog_ID, CHARINDEX('-', Catalog_ID) - 1)  
) z (ERP_ID) 

Hinweise: [1] CONVERT(XML, ...) die Quellzeichenfolge in XML konvertieren: -- <root><i>ABB</i><i>FET</i><i>abb</i><i>98693989-121966</i><i>20170304052411709.csv</i></root>

[2] Als nächstes können wir diese XML betrachten als ein Array von <i> Elementen und wie jedes andere Array können wir auf ein Element zugreifen, indem Sie den Index (1 basiert) verwenden, also: (root/i)[4]. Das Ergebnis ist '98693989-121966' (siehe CROSS APLLY (...) y).

[3] Der letzte Schritt besteht darin, ERP_ID mit LEFT(..., CHARINDEX('-', ...)-1) zu extrahieren.

[4] Die erste Annahme ist, dass die Quellzeichenfolge keine XML-reservierten Zeichen enthält (zB <). Zweite Annahme ist, dass die Quellzeichenfolge folgendes Muster hat: String1_String2_String3_String4...etc... und String4 enthalten die - Zeichen.

Demo

0

Ich denke, in Ihrem Fall REVERSE() verwendet, kann mehr Sinn wie diese machen:

declare @t nvarchar(max) = 'ABB_FET_abb_98693989-121966_20170304052411709.csv'; 
      -- my points:   ^   ^
select SUBSTRING(@t, 
                  -- start cutting 
    LEN(@t) -            -- from end of text by 
    CHARINDEX('_', REVERSE(@t),       -- trying to find first '_' char but 
       PATINDEX('%[-_]%', REVERSE(@t)) + 1) + 2, -- after first '-' or '_' char 
                  -- finish cutting by length of those 
    CHARINDEX('_', REVERSE(@t), 
       PATINDEX('%[-_]%', REVERSE(@t)) + 1) -  
    PATINDEX('%[-_]%', REVERSE(@t)) - 1); 
0

Noch eine andere Option:

Verwendung praktisch jede Parse/Split-Funktion im Zusammenspiel mit Ein CROSS APPLY macht

Beispiel

Declare @YourTable table (ID int,SomeCol varchar(500)) 
Insert Into @YourTable values 
(1,'ABB_FET_abb_98693989-121966_20170304052411709.csv') 
,(2,'XXX_YYY_zzz_12345678-123456_20170304052411709.csv') 

Select A.ID 
     ,[ERP ID]  = left(B.RetVal,charindex('-',B.RetVal)-1) 
     ,[CATALOG ID] = B.RetVal 
From @YourTable A 
Cross Apply (Select * from [dbo].[udf-Str-Parse-8K](A.SomeCol,'_') Where RetVal like '%-%') B 

Returns

ID ERP ID  CATALOG ID 
1 98693989 98693989-121966 
2 12345678 12345678-123456 

Die Funktion Parse verwendet, wenn Sie interessieren

CREATE FUNCTION [dbo].[udf-Str-Parse-8K] (@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','||')