[原創]sqlserver2005 從大文本字段中查找某關鍵字對應的內容

在我自己工作中,要處理各種不同電子病例模板的數據,一些電子病例數據存放於數據庫的大文本字段中,在我們自己系統中又要求重要的域要分開和提供接口供別人調用,我們需要把這些數據進行拆分,如拆分出:

入院情況;出院時間;住院經過;出院情況;出院醫囑;出院囑託;出院帶藥;入院診斷;出院診斷;病理診斷;
因爲模板不同,每個域的位置會不一樣或者沒有,所以我決定寫一個函數來處理,下面我說一下我的做法:

字段內容如:

<table id="table1" width="100%" border="0">      <tbody>          <tr>              <td align="center" colspan="6" style="height: 48px"><font color="#000000"><span class="title" id="_ctl0_C1_Label1">出院記錄</span> </font></td>          </tr>          <tr>              <td style="width: 27%"><span class="boldText">姓名:</span> <span class="text" id="_ctl0_C1_lbName">王XXX</span></td>              <td style="width: 25%"><span class="boldText">性別:</span> <span class="text" id="_ctl0_C1_lbSex">男性</span></td>              <td style="width: 19%"><span class="boldText">年齡:</span> <span class="text" id="_ctl0_C1_lbAge">57歲</span></td>              <td style="width: 29%"> </td>          </tr>          <tr>              <td><span class="boldText">入院時間:</span> <span class="text" id="_ctl0_C1_tbInHosTime">2013-01-09</span></td>              <td><span class="boldText">出院時間:</span> <span class="text" id="_ctl0_C1_tbOutHosTime">2013-01-15</span></td>              <td><span class="boldText">住院天數:</span> <span class="text" id="_ctl0_C1_tbDays">6</span> 天</td>              <td> </td>          </tr>          <tr>              <td valign="top" colspan="4"><span class="boldText">入院診斷:</span> <span class="text" id="_ctl0_C1_tbInDiag">1.眩暈綜合徵 2.胃癌術後 3.左下肢靜脈血栓形成</span></td>          </tr>          <tr>              <td valign="top" colspan="4"><span class="boldText">出院診斷:</span> <span class="text" id="_ctl0_C1_tbOutDiag">1.眩暈綜合徵 2.胃癌術後 3.左下肢靜脈血栓形成 4.2型糖尿病 5.輕度貧血(缺鐵性) 6.慢性乙型病毒性肝炎</span></td>          </tr>          <tr>              <td valign="top" colspan="4"><span class="boldText">入院情況:</span><span class="txt-indent" id="_ctl0_C1_tbBlDiag">患者,男性,57歲,因“頭暈4小時”入院。浙一醫院胃癌行根治術後病史7月,術後病理活檢示胃潰瘍型低分化腺癌,部分印戒細胞癌伴淋巴結轉移性癌,已行8次化療,左下肢靜脈血栓形成病史7月,目前口服華法林片。查體:T37.0℃ P62次/分 R18次/分 BP123/68mmHg,神志清,呼吸平穩,口脣無發紺,鎖骨上淋巴結未及腫大,雙肺未及羅音,心率62次/分,律齊,未及雜音,腹平軟,無壓痛及反跳痛,腹部可見豎直手術疤痕,約8cm,癒合佳,肝脾肋下未及,雙下肢無水腫;專科檢查:右利手,言語流利,瞳孔等大約0.3cm,對光反射靈敏,口角無歪斜,伸舌居中,頸軟,指鼻試驗準確,四肢肌力5級,雙側巴氏徵陰性。輔助檢查:2012-05-14,本院,浙一醫院,胃鏡病理活檢示胃潰瘍型低分化腺癌,部分印戒細胞癌伴淋巴結轉移性癌;B超示左髂外靜脈、左股總靜脈、左股淺靜脈血栓形成,左下肢動脈血流通暢。 </span></td>          </tr>          <tr id="_ctl0_C1_tr_blbg">              <td valign="top" colspan="4"><span class="boldText">檢驗報告:</span><span class="txt-indent" id="_ctl0_C1_tbOutBlbg">2013-01-09 11:17查急常規+CRP+表抗:白細胞計數 4.0*10^9/L,血紅蛋白 90g/L,血小板計數 214*10^9/L,中性粒細胞比率 45.2%,平均血紅蛋白含量 25.6pg,平均血紅蛋白濃度 317g/L,血小板體積分佈寬度 9.2%,C-反應蛋白 1.4mg/L,乙肝表面抗原篩查 陽性;2013-01-09 11:24查凝血功能全套(急):國際標準化比值 1.19;2013-01-09 11:44查急診心肌酶譜+TnI定量:抗鏈球菌溶血素"O" 202IU/ml;2013-01-09 14:26查糖化血紅蛋白:HbA1C(NGSP) 7.9%,HbA1C(IFCC) 63mmol/mo,eGA(估算平均血糖) 9.97mmol/L,總糖化血紅蛋白 10.6%;2013-01-10 09:31查糖化血紅蛋白:HbA1C(NGSP) 7.7%;2013-01-10 09:50查凝血功能全套:國際標準化比值 0.99;2013-01-10 12:38查乙肝定量:乙肝表面抗原(定量) >250.00IU/ml,乙肝核心抗體(定量) 13.57S/CO;2013-01-10 13:25查糖耐量二次(G+I+C):空腹血糖 7.79mmol/L,餐後二小時血糖 13.03mmol/L,肝腎功能、血脂、電解質、甲狀腺功能、腫瘤標誌化驗基本正常;2013-01-12 11:27查凝血功能全套:國際標準化比值 1.11;2013-01-14 10:07查凝血功能全套:國際標準化比值 1.10。</span></td>          </tr>          <tr>              <td valign="top" colspan="4"><span class="boldText">診治經過:</span> <span class="txt-indent" id="_ctl0_C1_tbProcess">予保護胃粘膜、抗凝,改善循環、營養神經及支持對症等治療。</span></td>          </tr>          <tr id="_ctl0_C1_trJc" style="display: none">              <td valign="top" colspan="4">診療期間主要檢查結果:</td>          </tr>          <tr id="_ctl0_C1_trJcjg" style="display: none">              <td valign="top" colspan="4"> </td>          </tr>          <tr>              <td valign="top" colspan="4"><span class="boldText">出院情況:</span><span class="txt-indent" id="_ctl0_C1_tbOutHosRecord">患者血壓穩定,無頭痛、頭暈,無視物旋轉,飲食、睡眠良好,無噁心、嘔吐,無畏寒、發熱,無胸悶、氣促及呼吸困難,大小便無殊,查體:神志清,言語流利,對答切題,肺部聽診無羅音,心律齊,腹平軟,肝脾肋下未觸及,四肢肌力5級,右手握力稍弱,持物可,兩側巴氏徵(-);病情穩定,今要求出院,囑其注意休息,繼續用藥,定期複查。  </span></td>          </tr>          <tr>              <td valign="top" colspan="4"><span class="boldText">療效評價:</span> <span class="text" id="_ctl0_C1_lbLxpj">不選</span></td>          </tr>          <tr>              <td valign="top" colspan="4" style="height: 22px"><span class="boldText">出院醫囑:</span></td>          </tr>          <tr>              <td valign="top" colspan="4"><span style="font-size: 14px">  出院康復指導及注意事項:</span><span class="text" id="_ctl0_C1_lblZysx">低脂、糖尿病飲食,忌菸酒,適當活動,定期複查,繼續用藥,監測血糖、凝血功能。</span></td>          </tr>          <tr id="_ctl0_C1_trfzsj">              <td valign="top" colspan="4"><span style="font-size: 14px">  複診時間:</span><span class="text" id="_ctl0_C1_lblFzsj">門診隨訪,監測血糖、凝血功能。</span></td>          </tr>          <tr id="_ctl0_C1_trcydy">              <td valign="top" colspan="4"><span style="font-size: 14px">  出院帶藥:</span></td>          </tr>          <tr>              <td class="txt-indent" valign="top" colspan="4">  <span id="_ctl0_C1_tbOutAdvice" style="font-size: 14px">甲鈷胺片500ug tid,呋喃硫胺片50mg tid。</span></td>          </tr>          <tr>              <td colspan="4">              <table width="100%">                  <tbody>                      <tr>                          <td width="70%"> </td>                          <td><span class="boldText">醫師簽名:</span><span class="text" id="_ctl0_C1_tbDoctor">李海霞</span></td>                      </tr>                      <tr>                          <td> </td>                          <td><span class="boldText">記錄日期:</span><span class="text" id="_ctl0_C1_tbDateTime">2013-01-14</span></td>                      </tr>                  </tbody>              </table>              </td>          </tr>      </tbody>  </table>

首先進行去HTML或XML標記處理,使用正則表達式,sqlserver2005使用正則有兩種,一種是使用ole自動化調用vbscript,另一種是用c#編寫sqlserver CLR項目建立自定義函數,我使用的前者。正則函數摘於網上:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

/*描述:正則式運算函數*/
CREATE   function   [dbo].[regexReplace]   
(   
  @source   varchar(5000),         --原字符串   
  @regexp   varchar(1000),         --正則表達式   
  @replace   varchar(1000),       --替換值   
  @globalReplace   bit   =   0,       --是否是全局替換   
  @ignoreCase   bit   =   0               --是否忽略大小寫   
)   
returnS   varchar(1000)   AS   
begin   
  declare   @hr   integer   
  declare   @objRegExp   integer   
  declare   @result   varchar(5000)   
    
  exec   @hr   =   sp_OACreate   'VBScript.RegExp',   @objRegExp   OUTPUT   
  IF   @hr   <>   0   begin   
  exec   @hr   =   sp_OADestroy   @objRegExp   
  return   null   
  end   
  exec   @hr   =   sp_OASetProperty   @objRegExp,   'Pattern',   @regexp   
  IF   @hr   <>   0   begin   
  exec   @hr   =   sp_OADestroy   @objRegExp   
  return   null   
  end   
  exec   @hr   =   sp_OASetProperty   @objRegExp,   'Global',   @globalReplace   
  IF   @hr   <>   0   begin   
  exec   @hr   =   sp_OADestroy   @objRegExp   
  return   null   
  end   
  exec   @hr   =   sp_OASetProperty   @objRegExp,   'IgnoreCase',   @ignoreCase   
  IF   @hr   <>   0   begin   
  exec   @hr   =   sp_OADestroy   @objRegExp   
  return   null   
  end     
  exec   @hr   =   sp_OAMethod   @objRegExp,   'Replace',   @result   OUTPUT,   @source,   @replace   
  IF   @hr   <>   0   begin   
  exec   @hr   =   sp_OADestroy   @objRegExp   
  return   null   
  end   
  exec   @hr   =   sp_OADestroy   @objRegExp   
  IF   @hr   <>   0   begin   
  return   null   
  end   
  return   @result   
end   


然後最主要的處理函數:

CREATE FUNCTION [dbo].[Func_GetDomainFromText](@value VARCHAR(MAX),@keyword VARCHAR(20))
RETURNS VARCHAR(MAX)
/*
 * 描述:從備註信息中找出某部分數據,如出院診斷。
 * 作者:羅毅
 * 例子:select top 20 dbo.Func_GetDomainFromText(LeaveSituation,'出院診斷') FROM RS_MyTable
*/
BEGIN
	--先去掉Html符號
	DECLARE @T VARCHAR(MAX)
	SET @T = dbo.regexReplace(@value,'<.+?>', '', 1, 1)	
	
	--預設置節點
	DECLARE @Items TABLE(Name varchar(20),Pos INT)
	INSERT INTO @Items VALUES('入院情況',CHARINDEX('入院情況',@T))
	INSERT INTO @Items VALUES('出院時間',CHARINDEX('出院時間',@T))
	INSERT INTO @Items VALUES('住院經過',CHARINDEX('住院經過',@T))
	INSERT INTO @Items VALUES('出院情況',CHARINDEX('出院情況',@T))
	INSERT INTO @Items VALUES('出院醫囑',CHARINDEX('出院醫囑',@T))
	INSERT INTO @Items VALUES('出院囑託',CHARINDEX('出院囑託',@T))
	INSERT INTO @Items VALUES('出院帶藥',CHARINDEX('出院帶藥',@T))
	INSERT INTO @Items VALUES('入院診斷',CHARINDEX('入院診斷',@T))
	INSERT INTO @Items VALUES('出院診斷',CHARINDEX('出院診斷',@T))
	INSERT INTO @Items VALUES('病理診斷',CHARINDEX('病理診斷',@T))
	DELETE FROM @Items WHERE Pos = 0

	--獲取keyword對應的位置
	DECLARE @p1 INT
	DECLARE @p2 INT
	DECLARE @F  INT
	DECLARE @Res VARCHAR(MAX)
	SET @F = 5
	SET @p1 = -1
	SET @p2 = -1
	SET @p1 = CHARINDEX(@keyword,@T)
	IF @p1 <= 0 RETURN ''
	SELECT TOP 1 @p2=Pos FROM @Items WHERE Pos > @p1 ORDER BY Pos
	
	IF (@p2 <= @p1) 
		--當前關鍵字在組中位於最後,則取後面所有數據
		SET @Res = SUBSTRING(@T,@p1+@F,len(@T)-@p1-@F)
	ELSE 
		--這裏的偏移量5,是因爲文本中存在冒號,如“出院診斷:”
		SET @Res = SUBSTRING(@T,@p1+@F,@p2-@p1-@F) 
	RETURN @Res
END


如有不足之處,希望大家指出,我即時修改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章