☰
卫宁电子病历表结构拆解:HIS对接核心表关联与查询避坑指南
2026/10/11 16:15:21 网站建设 项目流程

简介:卫宁电子病历表结构文档面向医院信息管理者、IT技术人员及医疗信息化研究人员,系统梳理了卫宁EMR 5.0的数据库设计框架,帮助读者理解临床信息系统的数据模型与标准化规范。资源为单个doc文件,压缩包约13.92MB,内容涵盖800多张数据表的说明、字段定义、类型、长度及值域备注,涉及职工代码库、医疗项目库、药品分类库、科室与病区代码库等基础模块,并延伸至凭证类型、收费大项目、医保分类、药房代码等财务收费管理,以及诊断代码、职称编码等医疗信息标准化内容。文档还体现了数据互操作性与安全保密设计思路,便于不同部门与机构间共享信息。目前已有1543人学习下载,适合用于优化系统结构、提升用户体验及开展医疗大数据分析时对照查阅。

1. 卫宁电子病历表结构:一份让 HIS 对接少走弯路的拆解思路

如果你正在对接医院信息系统,大概率绕不开卫宁健康这套电子病历。HIS、LIS、PACS 各跑各的,最后都要往电子病历里汇。问题来了:病历文书、医嘱、检验检查结果、护理记录,这些数据在卫宁的库里到底怎么存的?表与表之间靠什么字段串起来?为什么查出来的病历总是缺胳膊少腿?我见过太多团队拿到一份《卫宁电子病历表结构.doc》就以为拿到了通关文牒,结果一上手发现文档只列了字段名,没讲关联逻辑,照样翻车。这篇笔记不打算复述那份文档,而是把卫宁电子病历表结构里最常打交道的几组核心表、字段含义、关联路径和查询陷阱拆开讲。适合正在做 HIS 集成、CDR 建设、病历数据抽取的工程师,也适合需要从病历库里捞数据做质控或科研的同行。读完你至少能自己画出病历主表到明细表的关联草图,知道哪些字段是坑,哪些索引必须建。

2. 卫宁电子病历表结构里到底有哪些核心表:从病历主索引到临床明细

2.1 病历主表与患者主索引的绑定关系

卫宁电子病历的库表设计,核心思路是“一次就诊一条主记录,多次文书挂明细”。最顶层的表通常叫EMR_PATIENT或PATIENT_INFO,存患者基本信息,比如PATIENT_ID、PATIENT_NAME、ID_CARD、BIRTH_DATE。往下是就诊表,常见命名EMR_VISIT或VISIT_INFO,关键字段有VISIT_ID、PATIENT_ID、VISIT_TYPE(门诊/急诊/住院)、ADMISSION_DATE、DISCHARGE_DATE。再往下才是病历文书主表,比如EMR_DOCUMENT,字段包括DOCUMENT_ID、VISIT_ID、DOC_TYPE、DOC_TITLE、CREATE_TIME、CREATOR_ID。这三层靠PATIENT_ID和VISIT_ID串联。很多新手直接拿PATIENT_ID去查病历,结果把患者历史上所有就诊记录全捞出来,数据量爆炸。正确做法是先锁定VISIT_ID,再关联文书表。另外注意,卫宁有些版本把门诊和住院的就诊表分开,比如OUTP_VISIT和INP_VISIT,写查询前先确认医院实际部署的是哪套。

2.2 临床文书明细表:病程、护理、手术记录的存储差异

病历文书不是一张表装所有内容。卫宁通常按文书类型拆表,比如病程记录EMR_PROGRESS_NOTE、护理记录EMR_NURSING_RECORD、手术记录EMR_OPERATION_RECORD。这些表结构类似:都有DOCUMENT_ID关联主表,有CONTENT或CONTENT_XML存正文,有RECORD_TIME记录书写时间,有AUTHOR_ID记录书写人。差异在于专科字段,比如手术记录会有OPERATION_CODE、ANESTHESIA_TYPE,护理记录会有NURSING_LEVEL、VITAL_SIGNS。这里有个血泪经验:CONTENT字段在卫宁里可能是CLOB或BLOB,直接SELECT出来在客户端看可能是乱码或 XML 片段。我一般会先用DBMS_LOB.SUBSTR截取前 2000 字符看结构,确认是纯文本还是 XML。如果是 XML,还得用XMLTYPE或EXTRACTVALUE解析。另外,文书明细表的数据量增长极快,一个三甲医院一年能到千万级,查询时务必带上VISIT_ID或时间范围,否则全表扫描能把库拖垮。

2.3 医嘱与检验检查结果表如何挂到病历上

电子病历不只是文书,医嘱和检验检查结果也是重要组成部分。卫宁的医嘱表常见EMR_ORDER或DOCTOR_ORDER,关键字段ORDER_ID、VISIT_ID、ORDER_ITEM_NAME、ORDER_TIME、START_TIME、STOP_TIME、ORDER_STATUS。检验检查结果表通常叫LAB_RESULT和EXAM_RESULT,通过ORDER_ID或VISIT_ID关联。这里有个容易踩的坑:医嘱和检验结果不是一一对应,一个医嘱可能对应多个检验项目,一个检验项目也可能来自多条医嘱。关联时要用ORDER_ID加ITEM_CODE双条件,否则数据会翻倍。另外,卫宁的检验结果表里RESULT_VALUE是字符串类型,数值比较前得先CAST,不然'10' < '9'这种玄学问题会让你怀疑人生。我一般会在 ETL 层先做类型清洗,再往 CDR 里灌。

3. 从表结构到可执行 SQL:卫宁电子病历数据抽取的四个关键步骤

3.1 确认数据库类型与连接方式

卫宁电子病历底层数据库常见 Oracle 和 SQL Server 两种,少数新部署用 PostgreSQL。第一步不是写 SQL,而是确认版本和连接方式。Oracle 用sqlplus或 JDBC thin 驱动,SQL Server 用sqlcmd或 JDBC。连接串里注意字符集,Oracle 常见AL32UTF8,SQL Server 常见Chinese_PRC_CI_AS。如果字符集不对,中文姓名和病历内容会变问号。我一般先跑一条SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET';确认 Oracle 字符集。SQL Server 则用SELECT SERVERPROPERTY('Collation');。确认无误后再建连接池,别急着写大查询。

-- Oracle 确认字符集和版本 SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_LANGUAGE'); SELECT * FROM V$VERSION;
-- SQL Server 确认排序规则和版本 SELECT SERVERPROPERTY('Collation') AS Collation, SERVERPROPERTY('ProductVersion') AS Version;

逻辑说明:第一条 SQL 查 Oracle 字符集,确保中文不乱码;第二条查 SQL Server 排序规则,影响字符串比较和排序。参数说明:NLS_CHARACTERSET应为AL32UTF8或ZHS16GBK,如果是US7ASCII就得找 DBA 确认能否改。Collation含Chinese_PRC说明支持中文。

3.2 写一条能跑通的病历主表查询

确认连接后,先写一条最小可用查询,把患者、就诊、文书主表串起来。不要一上来就查所有字段,先拿关键字段验证关联逻辑。

-- 查询某患者某次住院的所有病历文书标题 SELECT p.PATIENT_ID, p.PATIENT_NAME, v.VISIT_ID, v.VISIT_TYPE, d.DOCUMENT_ID, d.DOC_TYPE, d.DOC_TITLE, d.CREATE_TIME FROM EMR_PATIENT p JOIN EMR_VISIT v ON p.PATIENT_ID = v.PATIENT_ID JOIN EMR_DOCUMENT d ON v.VISIT_ID = d.VISIT_ID WHERE p.ID_CARD = '110101199001011234' AND v.VISIT_TYPE = '住院' AND d.CREATE_TIME >= TO_DATE('2024-01-01', 'YYYY-MM-DD') ORDER BY d.CREATE_TIME DESC;

逻辑说明:三表内关联,用ID_CARD锁定患者,用VISIT_TYPE过滤住院,用CREATE_TIME限制时间范围。参数说明:ID_CARD换成实际身份证号;VISIT_TYPE取值需确认医院字典,常见'住院'、'门诊'、'急诊';TO_DATE是 Oracle 写法,SQL Server 用CONVERT(DATETIME, '2024-01-01', 120)。注意:如果EMR_VISIT表里门诊和住院分开,这里要改成INP_VISIT。

3.3 抽取病程记录正文的注意事项

拿到DOCUMENT_ID后,去明细表取正文。前面说过CONTENT可能是 CLOB,直接查会报错或截断。

-- Oracle 截取病程记录正文前 2000 字符 SELECT DOCUMENT_ID, DBMS_LOB.SUBSTR(CONTENT, 2000, 1) AS CONTENT_PREVIEW, RECORD_TIME, AUTHOR_ID FROM EMR_PROGRESS_NOTE WHERE DOCUMENT_ID = 'DOC20240101001';

逻辑说明:DBMS_LOB.SUBSTR用于 CLOB 字段截取,避免全量拉取导致内存溢出。参数说明:第一个参数是字段名,第二个是截取长度,第三个是起始位置。如果要全量导出,建议用DBMS_LOB.READ分片读取,或者直接在 ETL 工具里配置 CLOB 映射。SQL Server 对应SUBSTRING(CONTENT, 1, 2000),但CONTENT是NVARCHAR(MAX)时可以直接CAST。

3.4 医嘱与检验结果的关联查询模板

最后把医嘱和检验结果串起来。这条查询在质控和科研里用得最多。

-- 查询某次住院的医嘱及对应检验结果 SELECT o.ORDER_ID, o.ORDER_ITEM_NAME, o.ORDER_TIME, l.ITEM_CODE, l.ITEM_NAME, l.RESULT_VALUE, l.UNIT, l.REFERENCE_RANGE FROM EMR_ORDER o LEFT JOIN LAB_RESULT l ON o.ORDER_ID = l.ORDER_ID AND o.ITEM_CODE = l.ITEM_CODE WHERE o.VISIT_ID = 'VISIT20240101001' AND o.ORDER_STATUS = '已执行' ORDER BY o.ORDER_TIME, l.ITEM_CODE;

逻辑说明:用LEFT JOIN保留没有检验结果的医嘱,用ORDER_ID加ITEM_CODE双条件避免笛卡尔积。参数说明:ORDER_STATUS取值需确认字典,常见'已执行'、'已停止'、'未执行';RESULT_VALUE是字符串,数值计算前先CAST。注意:如果LAB_RESULT表数据量大,ORDER_ID和ITEM_CODE上必须有联合索引,否则这条查询能跑几分钟。

4. 卫宁电子病历表结构对接避坑:五条血泪经验

4.1 现象:查出来的病历数量比实际少一半

原因:卫宁有些版本把病历文书主表按院区或科室分表,比如EMR_DOCUMENT_01、EMR_DOCUMENT_02,只查一张表自然漏数据。解决:先查USER_TABLES或INFORMATION_SCHEMA.TABLES看有没有分表,再用UNION ALL合并,或者直接查视图V_EMR_DOCUMENT(如果医院建了的话)。

4.2 现象:中文姓名和病历内容显示为问号

原因:数据库字符集是US7ASCII或客户端NLS_LANG没设对。解决:Oracle 客户端设NLS_LANG=AMERICAN_AMERICA.AL32UTF8,SQL Server 连接串加characterEncoding=UTF-8。如果库本身字符集不对,只能找 DBA 导出时转码。

4.3 现象:CLOB 字段查询报 ORA-00932

原因:直接对 CLOB 用=、LIKE、ORDER BY会报错。解决:用DBMS_LOB.INSTR判断包含,用DBMS_LOB.SUBSTR截取,排序时先转VARCHAR2但注意长度限制。SQL Server 的NVARCHAR(MAX)也有类似限制,ORDER BY前先CAST成NVARCHAR(4000)。

4.4 现象:医嘱和检验结果关联后数据翻倍

原因:LAB_RESULT表里一个ORDER_ID对应多个ITEM_CODE,而EMR_ORDER里也有多个ITEM_CODE,只用ORDER_ID关联会笛卡尔积。解决:必须加ITEM_CODE作为第二关联条件,或者先按ORDER_ID聚合检验结果再关联。

4.5 现象:查询跑几分钟不出结果

原因:没走索引,或者时间范围太大。解决:确认VISIT_ID、DOCUMENT_ID、ORDER_ID上有没有索引;查询必须带VISIT_ID或CREATE_TIME范围;大表查询放在业务低峰期跑,或者用物化视图预聚合。

5. 进阶:用元数据反查卫宁电子病历表结构的真实关联

5.1 从数据字典里挖出隐藏的外键关系

卫宁的文档不一定写全外键,但数据字典里有线索。Oracle 查USER_CONSTRAINTS和USER_CONS_COLUMNS,SQL Server 查INFORMATION_SCHEMA.KEY_COLUMN_USAGE。我一般先跑一条查询把所有外键关系拉出来,再对照文档验证。

-- Oracle 查询指定表的外键关系 SELECT a.TABLE_NAME, a.COLUMN_NAME, c.TABLE_NAME AS REF_TABLE, c.COLUMN_NAME AS REF_COLUMN FROM USER_CONS_COLUMNS a JOIN USER_CONSTRAINTS b ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME JOIN USER_CONS_COLUMNS c ON b.R_CONSTRAINT_NAME = c.CONSTRAINT_NAME WHERE b.CONSTRAINT_TYPE = 'R' AND a.TABLE_NAME IN ('EMR_DOCUMENT', 'EMR_ORDER', 'LAB_RESULT');

逻辑说明:通过USER_CONSTRAINTS找外键约束,再关联USER_CONS_COLUMNS拿到列名。参数说明:CONSTRAINT_TYPE = 'R'表示外键;TABLE_NAME换成你要查的表。如果查出来为空,说明数据库没建物理外键,只能靠字段名猜关联,这时候VISIT_ID、DOCUMENT_ID、ORDER_ID就是关键线索。

5.2 用字段注释补全文档缺失的语义

卫宁的字段名很多是缩写,比如DOC_TYPE、ORDER_STATUS,光看名字不知道取值。查字段注释能省很多事。

-- Oracle 查询表和字段注释 SELECT TABLE_NAME, COLUMN_NAME, COMMENTS FROM USER_COL_COMMENTS WHERE TABLE_NAME IN ('EMR_DOCUMENT', 'EMR_ORDER') ORDER BY TABLE_NAME, COLUMN_NAME;

逻辑说明:USER_COL_COMMENTS存字段注释,USER_TAB_COMMENTS存表注释。参数说明:如果注释是英文或为空,只能去问医院信息科要数据字典,或者从业务系统界面反推。我一般会把注释导出成 Excel,和文档对照着看,缺的字段重点标记。

5.3 验证关联逻辑的土办法

文档和字典都查完后,别急着写正式 ETL。先拿一个真实VISIT_ID,手动跑一遍关联查询,看结果条数是否合理。比如一次住院的病程记录通常 5 到 20 条,如果查出来 200 条,说明关联条件错了。再拿一个已知的检验结果,反查ORDER_ID,看能不能对上医嘱。这个土办法能拦住八成以上的关联错误。我自己的习惯是:每对接一张新表,先写三条验证 SQL,分别查主表、明细表、关联结果,确认无误再进 ETL 流程。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询