2017-06-13 12 views
-1

MS SQL構文のみを使用して生のHL7データを解析するこのコードを共有します。これは、すべての| ^デリミタを作成し、各データを行として格納します。 私はこれを共有したいと思いました。なぜなら、私は、HL7メッセージをSQL構文で厳密に解析する方法を探していて、リソースを見つけることができなかったからです。MS SQL構文のみを使用してHL7デリミタを解析する方法

これは、HL7メッセージをSQLデータベースにインポートする最も効率的な方法ではありません。他のより良い方法(C#アプリ - HL7> XML> DB、サードパーティ製ソフトウェア、BULK INSERTなど)があります。

これは、 ^デリミタを作成し、TempSplitテーブルとTempSplit2テーブルの行に格納します。ここでは、元のHL7ファイルをデータベース(つまり、SSIS)にインポートする方法があるという前提があります。その後、TempSplit2の下に格納された結果をSQL Segmentテーブルにマップできます。

IDカラム=各値の位置|

ID2欄=あなたが2列に(そのまま)生HL7ファイルをインポートすることができ最初の試験として^

間の各値の位置。

Row  val          Filename 
    ------------------------------------------------------------------ 
    1  MSH|^~\&|EIH7|      HL7_Filename.dat 
      AB-PBA^AB PBA^ISO|Company|TestComp| 
      20160830230713||ADT^A04|23071 
      408302016752373|P|2.6|  

EDIT:以下scsimonで述べたように、カーソルが二回ループし、むしろ、あなただけの必要なものよりも、すべてデータを解析し、以下のサンプルを参照してください。私の現在のプロジェクトでは、これは重要でしたが、おそらくあなたのものではなかったでしょう。 |

USE <yourdb> 
Go 
set nocount on 


Create table dbo.TempSplit(
        filename varchar(MAX), 
        RecordType varchar(MAX), 
        value varchar(MAX) , 
        id int) 
Create table dbo.TempSplit2(
        filename varchar(MAX), 
        RecordType varchar(MAX), 
        value varchar(MAX) , 
        id int , 
        subvalue varchar(MAX) , 
        id2 int) 

truncate table dbo.TempSplit 
truncate table dbo.TempSplit2 
DECLARE HL7_Cursor CURSOR FOR select distinct filename 
from <your raw HL7 table> 
DECLARE @tempid varchar(max) 

Open HL7_Cursor 
Fetch next from hl7_cursor into @tempid 
While @@FETCH_STATUS = 0 
BEGIN 
Declare @Rowcnt int=0 
DECLARE HL7_Cursor2 CURSOR FOR select val from <<your raw HL7 table>> where filename = @tempid 
DECLARE @tempid2 varchar(max) 

Open HL7_Cursor2 
Fetch next from hl7_cursor2 into @tempid2 
While @@FETCH_STATUS = 0 
      BEGIN 
      set @Rowcnt = @Rowcnt +1 
      DECLARE @RtnValue table 
       (
        value varchar(MAX) , 
        id int 
       ) 

      DECLARE @result varchar(1000), 
        @List varchar(MAX), 
        @SplitOn varchar(5), 
        @GetIndex smallint, 
        @ID int, 
        @val varchar(max), 
        @recordid varchar(max), 
        @filename varchar(1000) , 

        @cnt int=0 
      SET @list = @tempid2 

      SET @SplitOn = '|' 
      SET @GetIndex = 0 

      DECLARE @start INT, @end INT 
      SELECT @start = 1, @end = CHARINDEX(@SplitOn, @list) 
      WHILE @start < LEN(@list) + 1 BEGIN 
       BEGIN 
       IF @end = 0 
       begin 
       SET @end = LEN(@list) + 1 
       end 
       END 

       Insert Into @RtnValue (id,value) 
       Select @cnt,SUBSTRING(@list, @start, @end - @start) 
       SET @start = @end + 1 
       SET @end = CHARINDEX(@SplitOn, @list, @start) 
       set @cnt= @cnt+1  
       END 

       insert into dbo.TempSplit 
       select @tempid filename, 
         case when 
         (Select count(value) 
         from @RtnValue) = 0 then value 
         else 
         (Select value 
         from @RtnValue 
         where id =0)end Recordtype, 
         value,id,@Rowcnt from @RtnValue 
         delete from @RtnValue 
         set @cnt =0 


FETCH NEXT From HL7_Cursor2 into @tempid2          
END      
Close hl7_cursor2 
deallocate hl7_cursor2 

FETCH NEXT From HL7_Cursor into @tempid          
END      
Close hl7_cursor 
deallocate hl7_cursor 

truncate table dbo.TempSplit2 
DECLARE HL7_Cursor3 CURSOR FOR select * from dbo.TempSplit 
DECLARE @file varchar(max),@rt varchar(max),@valu varchar(max),@idz int 
,@rowcnt2 int 

Open HL7_Cursor3 
Fetch next from hl7_cursor3 into @file,@rt,@valu,@idz,@rowcnt2 
While @@FETCH_STATUS = 0 
     BEGIN 
      DECLARE @RtnValue2 table 
       (

        value varchar(MAX) , 
        id int, 
        filename varchar(MAX) 
       ) 

      DECLARE @result2 varchar(1000), 
        @List2 varchar(MAX), 
        @SplitOn2 varchar(5), 
        @GetIndex2 smallint, 
        @ID2 int, 
        @val2 varchar(max), 
        @recordid2 varchar(max), 
        @filename2 varchar(1000) , 
        @cnt2 int=0 
      SET @list2 =  @valu 

      SET @SplitOn2 = '^' 
      SET @GetIndex2 = 0 

      DECLARE @start2 INT, @end2 INT     
      SELECT @start2 = 1, @end2 = CHARINDEX(@SplitOn2, @list2) 
      WHILE @start2 < LEN(@list2) + 1 BEGIN 
       BEGIN 
       IF @end2 = 0 
       begin 
       SET @end2 = LEN(@list2) + 1 
       end 
       END 
      Insert Into @RtnValue2 (id,value,filename) 
      Select @cnt2,SUBSTRING(@list2, @start2, @end2 - @start2) ,@file 
      SET @start2 = @end2 + 1 
      SET @end2 = CHARINDEX(@SplitOn2, @list2, @start2) 
      set @cnt2= @cnt2+1 
      END 
      insert into dbo.TempSplit2 
     select @file,@rt,@valu,@idz,value,id,@rowcnt2 from @RtnValue2 
     delete from @RtnValue2 
     set @cnt2 =0 

FETCH NEXT From HL7_Cursor3 into @file,@rt,@valu,@idz ,@rowcnt2         
End       
Close hl7_cursor3 
deallocate hl7_cursor3 
+1

を立ち往生している一部の人に助けになりますTally + Table/72993 /)はあなたが持っているものは確かに恐ろしい性能を発揮します**これらはあなたの文字列を区切り記号から分けます。この場合、文字列の[substring()](https://docs.microsoft.com/en-us/sql/t-sql/functions/substring-transact-sql)を分割してからあなたが望む列を選択してください。あなたが必要とする唯一のカーソルは、最も外側のカーソルである別々のファイルをループすることです。残りの部分は削除されます – scsimon

+0

適切な区切り文字と[BULK INSERT](https://docs.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql)あなたが必要としないものを落とす。 – scsimon

+0

ご意見ありがとうございます@scsimon。今のところ、これは私の仕事を終わらせる(パフォーマンスヒットはあるが)。私はあなたの入力を高く評価します。私は、BULK INSERTとスプリッターを調べます – Isaiah3015

答えて

0

のHL7メッセージの区切り文字を解析する必要があり、ポスト上のコード:それはここでは

を変更する自由を感じることはコードですと^を使用して、区切り記号を解析する場合は、別のカーソルを追加する必要があります。ここでからは、あなたが対応するテーブルに「RECORDTYPE」、「ID」と「ID2」に基づいてsubvalueデータをマッピングすることができ

Row filename   RecordType Value id Subvalue id2 RecordTypeID         
------------------------------------------------------------------ 
1  HL7_filename.dat MSH  MSH  0 MSH  0  1 
2  HL7_filename.dat MSH  ^~\&  1   0  1 
3  HL7_filename.dat MSH  ^~\&  1 ^~\& 1  1 
4  HL7_filename.dat MSH  EIH7  2 EIH7 0  1 

:ここ

は、それがどのようなものかの最終的な結果です。 RecordTypeIDカウンタは、同じセグメントが1つのファイルに複数回送信された場合に使用されます。

うまくいけば、これは私があなたをDVませんでしたが、あなたは本当に[これらのスプリッタの1](http://www.sqlservercentral.com/articles/をご覧ください

関連する問題