当前位置: 代码迷 >> SQL >> [原创]sqlserver2005 从大文本字段中查寻某关键字对应的内容
  详细解决方案

[原创]sqlserver2005 从大文本字段中查寻某关键字对应的内容

热度:67   发布时间:2016-05-05 12:32:02.0
[原创]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 ONset QUOTED_IDENTIFIER ONgo/*描述:正则式运算函数*/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,@[email protected],len(@T)-@p1-@F)	ELSE 		--这里的偏移量5,是因为文本中存在冒号,如“出院诊断:”		SET @Res = SUBSTRING(@T,@[email protected],@p2-@p1-@F) 	RETURN @ResEND


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

2楼daling535昨天 11:07
4 rt`1
1楼daling535昨天 11:07
3
  相关解决方案