0

私はBIOと呼ばれるSQL Server 2005のテーブルの列を持っている - BIOの列のデータは以下のようにフォーマットされていますHTMLでラップされた文字列をSQLテーブルの列から新しいテーブルに抽出するにはどうすればよいですか?

<HTML><HEAD><TITLE></TITLE></HEAD><BODY><STRONG><A name=SN>AARTS</A>, <A name=GN>Michelle Marie</A>, </STRONG><A name=HO>B.Sc.</A>, <A name=HO>M.Sc.</A>, <A name=HO>Ph.D.</A>; <A name=OC>scientist, professor</A>; b. <A name=BC>St. Marys</A>, Ont. <A name=BY>1970</A>; <A name=PA>d. Wm. and H. Aarts</A>; <A name=ED>e. Univ. of Western Ont. B.Sc.(Hons.) 1994, M.Sc. 1997</A>; <A name=ED>McGill Univ. Ph.D. 2002</A>; <A name=MA>m. L. MacManus</A>; two children; <A name=PO>CANADA RESEARCH CHAIR IN SIGNAL TRANSDUCTION IN ISCHEMIA</A> and <A name=PO>ASST. PROF., DEPT. OF BIOL. SCI., UNIV. OF TORONTO SCARBOROUGH 2006&ndash;&nbsp;&nbsp;</A>; Postdoctoral Fellow, Toronto Western Hosp. 2000&ndash;06; Expert Cons., Auris Med. SAS, Montpellier, France; mem., Centre for the Neurobiol. of Stress; named INMHA Brainstar of the Year 2003; Bd. of Dirs. &amp; Fundraising Chair, N'Sheemaehn Childcare; mem., Soc. for Neurosci.; Cdn. Physiol. Soc.; Cdn. Assn. for Neurosci.; <A name=WK>co-author: 'Therapeutic Tools in Brain Damage' in <EM>Proteomics and Protein Interactions: Biology, Chemistry, Bioinformatics and Drug Design </EM>2005; 18 pub. journal articles</A>; Office: <A name=OF1_L1>1265 Military Trail</A>, <A name=OF1_CT>Scarborough</A>, <A name=OF1_PR>Ont.</A> <A name=OF1_PC>M1C 1A4</A>. </BODY></HTML> 

私はアンカータグすなわちのそれぞれから値を抽出する必要があります。

<A name=SN>AARTS</A> 

私は...これは私がこれまで持っているものである

結果セットのSNという列にAARTSを持っている必要があります

SELECT CONTACT_ID 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=SN>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=SN>', [BIO])) - CHARINDEX('<A name=SN>', [BIO])-11))) AS 'SN' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=GN>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=GN>', [BIO])) - CHARINDEX('<A name=GN>', [BIO])-11))) AS 'GN' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=HO>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=HO>', [BIO])) - CHARINDEX('<A name=HO>', [BIO])-11))) AS 'HO' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=OC>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=OC>', [BIO])) - CHARINDEX('<A name=OC>', [BIO])-11))) AS 'OC' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=PO>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=PO>', [BIO])) - CHARINDEX('<A name=PO>', [BIO])-11))) AS 'PO' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=BD>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=BD>', [BIO])) - CHARINDEX('<A name=BD>', [BIO])-11))) AS 'BD' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=PA>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=PA>', [BIO])) - CHARINDEX('<A name=PA>', [BIO])-11))) AS 'PA' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=BY>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=BY>', [BIO])) - CHARINDEX('<A name=BY>', [BIO])-11))) AS 'BY' 
    ,dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=ED>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=ED>', [BIO])) - CHARINDEX('<A name=ED>', [BIO])-11))) AS 'ED' 
FROM [cww].[dbo].[Contacts] 
ORDER BY CONTACT_ID 

私はそれから得られる結果は次のようになります。

CONTACT_ID SN GN HO OC PO DB PA BY ED 
3 AARON Raymond Leonard B.Sc. business coach, professional speaker, real estate entrepreneur D>AARON 
5 AATAMI Pita C.Q. business executive; Kuujjuaq 
7 ABBOTT Anthony C. P.C. lawyer Montreal 
8 ABBOTT Elizabeth M.A. historian Ottawa 
9 ABBOTT (Caroline) Louise D>ABBOTT writer, photographer, filmmaker Montreal 

を私が続けると、手動でそれぞれ異なる名前のアンカーのためのサブストリングのすべてを追加しますが、これに伴う問題は、私は "のすべてを知っていないということであることができますアンカーに使用されている「名前」という名前のテーブルがあり、このテーブルには22000以上のレコードがあります。同様に、すべてのBIOにすべてのアンカーがあるわけではないので、 'ABBOTT(Caroline)Louise'の結果を見ると 'HO'アンカーがないので、間違ったデータ 'D> ABBOTT'が返されますこれを見ても私が持っている限定的な結果ではあるが、いくつかのレコードには、私が想像する2'HOのような複数のアンカーが問題を引き起こすだろう...。最後の問題は、すべてのアンカー名が2文字なので、私はcharindexで使用しているそれらのものに間違っているでしょう..

これを行うには良い方法はありますか?どんな助けもありがとう。

UPDATE - 現在のレコードのアンカー名が存在しない場合、誤ったデータを削除するためにCASE文を追加しました。

SELECT CONTACT_ID 
    ,'SN' = 
     CASE 
      WHEN CHARINDEX('<A name=SN>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=SN>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=SN>', [BIO])) - CHARINDEX('<A name=SN>', [BIO])-11))) 
     END  
    ,'GN' = 
     CASE 
      WHEN CHARINDEX('<A name=GN>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=GN>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=GN>', [BIO])) - CHARINDEX('<A name=GN>', [BIO])-11))) 
     END 
    ,'HO' = 
     CASE 
      WHEN CHARINDEX('<A name=HO>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=HO>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=HO>', [BIO])) - CHARINDEX('<A name=HO>', [BIO])-11))) 
     END 
    ,'OC' = 
     CASE 
      WHEN CHARINDEX('<A name=OC>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=OC>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=OC>', [BIO])) - CHARINDEX('<A name=OC>', [BIO])-11))) 
     END 
    ,'PO' = 
     CASE 
      WHEN CHARINDEX('<A name=PO>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=PO>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=PO>', [BIO])) - CHARINDEX('<A name=PO>', [BIO])-11))) 
     END 
    ,'BD' = 
     CASE 
      WHEN CHARINDEX('<A name=BD>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=BD>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=BD>', [BIO])) - CHARINDEX('<A name=BD>', [BIO])-11))) 
     END 
    ,'PA' = 
     CASE 
      WHEN CHARINDEX('<A name=PA>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=PA>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=PA>', [BIO])) - CHARINDEX('<A name=PA>', [BIO])-11))) 
     END 
    ,'BY' = 
     CASE 
      WHEN CHARINDEX('<A name=BY>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=BY>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=BY>', [BIO])) - CHARINDEX('<A name=BY>', [BIO])-11))) 
     END 
    ,'ED' = 
     CASE 
      WHEN CHARINDEX('<A name=ED>', [BIO]) = 0 THEN NULL 
      ELSE dbo.udf_StripHTML(SUBSTRING([BIO], (CHARINDEX('<A name=ED>', [BIO]) + 11), (CHARINDEX('</A>', [BIO], CHARINDEX('<A name=ED>', [BIO])) - CHARINDEX('<A name=ED>', [BIO])-11))) 
     END 
--INTO [cww].[dbo].[BioDetails] 
FROM [cww].[dbo].[Contacts] 
ORDER BY CONTACT_ID 
+0

ouch;私はこれがちょうど私がデータベースにHTMLを保存していない**(とあなたのデータを取り戻すことを期待している)のために見た最良の勧告になったと思います。このテーブルには他にも多くの問題があります。抽出するデータを保持するためのテーブルセットを作成し、必要に応じて手動クエリを作成することをお勧めします。あなたが行くにつれて検証する...)。あなたがすべて完了したら、そのことを削除してください... –

+0

はい、誰かと仕事をすることの欠点です。この目的の全目的は、再利用可能なスクリプトを使用して、各タイプのアンカーのルックアップテーブルを使用してBIOカラムをリレーショナルデータに変換し、毎年新しいデータを取得することです。ウェブサイト... – tsdexter

+0

あなたはsqlサーバの人にフィールド型のXMLがありますか?それを使ってXMLを保存するhttp://msdn.microsoft.com/en-us/library/ms345117%28v=sql.90%29.aspx –

答えて

0

純粋にT-SQLでこれを行う方法がわかりません。

CONTACT_ID列とBIO列をアプリケーションに取り出すことができる場合は、結果セットを反復処理し、BIOデータをXMLとして解析し、XPathを使用して名前属性値とアンカー本体を取得し、新しいテーブルに挿入するデータ。存在する可能性のあるすべての名前が分からないので、テーブルが実行されるたびにテーブルを再作成する必要があるため、セット内のストア名をすべての行にわたって反復した後にSetを使用してcreate tableステートメント。

DBコードは純粋に幻想的ですが、ここではJava用のXOM XMLライブラリを使用してどのように行うことができるかを示すスニペットです。私はあなたの属性値が引用されていないのでこれがうまくいくとは思っていませんが、あなたはあまり好きではないパーサーを見つけることができるかもしれません。

ResultSet results = db.query("select CONTACT_ID, BIO from [cww].[dbo].[Contacts]"); 

Set<String> newTableColumns = new Set<String>(); 
newTableColumns.put("CONTACT_ID"); 

List<Map<String,String> > dataToInsert = new ArrayList<Map<String,String> >(); 
Builder parser = new Builder(); 

for (ResultRow resultRow : results) { // iterate over the result set 

    Map<String,String> rowDataToInsert = new HashMap<String,String>(); 
    rowData.put("CONTACT_ID", resultRow.get("CONTACT_ID")); 

    // parse the BIO data as an XML document 
    Document doc = parser.build(resultRow.get("BIO"), ""); 

    // query the document using XPath 
    Nodes namedAnchors = doc.query("//a[@name]"); 

    for (int nItr = 0; nItr < namedAnchors.size(); nItr++) { 

     Element anchor = (Element) namedAnchors.get(nItr); 
     String name = anchor.getAttributeValue("name"); 
     String anchorBody = anchor.getValue(); 

     newTableColumns.put(name); 
     rowDataToInsert.put(name, anchorBody); 

    } 

    // we've stored all the anchor data from this row, so put it away 
    dataToInsert.add(rowDataToInsert); 
} 

// create your table 
db.createTable("NEW_TABLE_NAME", newTableColumns); 

// insert into your new table 
db.batchInsert("NEW_TABLE_NAME", dataToInsert); 
+0

ありがとう、私はこのようなことをしようとしています。 – tsdexter

0

私は、contact_id、アンカー型と値を持つテーブルを作成してデータを解析し、それにレコードを追加し、その後、クロス集計でそれを吐き出すだろう。これにより、すべてのアンカータイプが何であるかを簡単に見つけることができます。アンカータイプが複数ある場合もありません。

また、データを複数回渡す必要がある場合や、 SQLのように)、例えばc#。

+0

アンカーの名前をアンカー列に解析するためのコード例を入力すると、特にC#が私の上にある可能性があります。この「クロス集計」と同様に、あなたは話します。 (私は本当にSQLの教祖ではない、私はより多くのhtml、CSS、js、PHP、.net、ルビーなどですが、少しSQLは時々仕事に付属しています... – tsdexter

関連する問題