简介卫宁电子病历表结构文档面向医院信息管理者、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 常见AL32UTF8SQL 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_LANGAMERICAN_AMERICA.AL32UTF8SQL Server 连接串加characterEncodingUTF-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_COLUMNSSQL 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 流程。希望帮到你。本文还有配套的精品资源点击获取