2016-09-29 7 views
0

ディレクトリパスの文字列を取り出し、その中の情報を別のテーブルの既存の列に解析したいと考えています。これは、レポート用のステージングテーブルを作成するためのものです。 ProjectNameが構造の変更に適用可能な場合、多くのディレクトリパスを解析します。文字で文字列を分割し、それを別のテーブルの複数の列に分解する

Data Example: 

Table1_Column1 
ProjectName\123456_ProjectShortName\Release_1\Iteration\etc 


Expected Output: 

Table2_Column1, Table2_Column2 
123456   ProjectShortName 

文字列を解析する方法を理解しましたが、ちょっと不器用で非効率なようです。これについてもっと良い構造がありますか?もう少し追加するには、これは、ProjectNameに基づいてステージングテーブルに直接シフトされている3つの他の列がシフトする前に操作する必要がある列です。

分割するUDFを作成して、データを移動するジョブ内で呼び出すか、別の方法がありますか?

+0

column1が123456で、ProjectNameでないルールは何ですか? –

+0

Column1は、ビジネスプロセスによって作成されたIDです。そのIDは、独自の列に分割する必要があります。彼らはtable2の任意の2つの列に行くことができます。 –

+0

あなたはパフォーマンススプリッタを求めましたが、これをチェックしてください:http://www.sqlservercentral.com/articles/Tally+Table/72993/ – scsimon

答えて

1

を必要に応じて、UDFは、ここではUDFのない方法です。
charindexとsubstringを使用して、そのパス文字列からパーツを取得します。

テーブル変数を使用する例:

declare @T table (Table1_Column1 varchar(100)); 
insert into @T values 
('ProjectName\123456_ProjectShortName\Release_1\Iteration\etc'), 
('OtherProjectName\789012_OtherProjectShortName\Release_2\Iteration\xxx'); 

select 
case 
when FirstBackslashPos > 0 and FirstUnderscorePos > 0 
then substring(Col1,FirstBackslashPos+1,FirstUnderscorePos-FirstBackslashPos-1) 
end as Table1_Column1, 
case 
when FirstUnderscorePos > 0 and SecondBackslashPos > 0 
then substring(Col1,FirstUnderscorePos+1,SecondBackslashPos-FirstUnderscorePos-1) 
end as Table1_Column2 
from (
    select 
    Table1_Column1 as Col1, 
    charindex('\',Table1_Column1) as FirstBackslashPos, 
    charindex('_',Table1_Column1) as FirstUnderscorePos, 
    charindex('\',Table1_Column1,charindex('\',Table1_Column1)+1) as SecondBackslashPos 
from @T 
) q; 

あなたは変数

declare @ProjectPath varchar(100); 
set @ProjectPath = 'ProjectName\123456_ProjectShortName\Release_1\Iteration\etc'; 

declare @FirstBackslashPos int = charindex('\',@ProjectPath); 
declare @FirstUnderscorePos int = charindex('_',@ProjectPath,@FirstBackslashPos); 
declare @SecondBackslashPos int = charindex('\',@ProjectPath,@FirstBackslashPos+1); 
declare @ProjectNumber varchar(30) = case when @FirstBackslashPos > 0 and @FirstUnderscorePos > 0 then substring(@ProjectPath,@FirstBackslashPos+1,@[email protected])end; 
declare @ProjectShortName varchar(30) = case when @FirstUnderscorePos > 0 and @SecondBackslashPos > 0 then substring(@ProjectPath,@FirstUnderscorePos+1,@[email protected]) end; 

select @ProjectNumber as ProjectNumber, @ProjectShortName as ProjectShortName; 

しかしi.m.h.o.に一つだけを計算したい場合真の正規表現マッチングをSQLサーバにもたらすCLRを加える価値があるかもしれません。 CHARINDEXとPATINDEXは正規表現ほど柔軟ではないので

+0

私は挿入できません。私は、その列のすべてのディレクトリパスを動的に解析する必要があります。そのような文字列リテラルはありません。 –

+0

これは間違いなく私が探しているものです。この方法を教えてくれてありがとう。 –

0

以下はSUPER Parserですが、8Kバイトに制限されています。返されるシーケンス番号に注意してください...私はcolumn1のは123456とない

Declare @String varchar(max) = 'ProjectName\123456_ProjectShortName\Release_1\Iteration\etc' 

Select * from [dbo].[udf-Str-Parse-8K](@String,'\') 

戻り

RetSeq RetVal 
1  ProjectName 
2  123456_ProjectShortName 
3  Release_1 
4  Iteration 
5  etc 

をPROJECTNAMEである理由のためのロジックにはまだ明確ではないですので、おそらくあなたは、そのOFFキーすることができます

CREATE FUNCTION [dbo].[udf-Str-Parse-8K] (@String varchar(max),@Delimiter varchar(10)) 
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 = Substring(@String, A.N, A.L) 
    From cte4 A 
); 
--Much faster than str-Parse, but limited to 8K 
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||') 
+0

この順序は、123456がその文字列に含まれるIDの例ですそれは分離する必要があります。 –