☰
用友数据库表名文档实战:从表名到SQL查询与数据集成
2026/10/14 11:52:52 网站建设 项目流程

简介:这份文档面向用友财务软件的运维人员、二次开发者和数据分析人员,系统整理了用友数据库中的核心表名及其业务含义,帮助读者快速定位总账、应收应付、成本核算、库存管理等模块对应的数据表。资源包内仅含1个doc文件,约30KB,以表格形式罗列了从Accessaries成套件表、AccInformation帐套参数表,到Ap系列收付款与核销表、Ar坏账计提表、CA成本会计系列表、CheckVouch盘点单等数百张表的编号、英文表名与中文说明,并覆盖到货质检、组装拆卸、发货委托代销等业务场景。目前已有108人学习下载。读者可借助这份参照表理解用友数据库结构,为报表定制、数据抽取、接口开发和系统维护提供查表依据,尤其适合需要梳理财务与供应链数据关系的中高级技术人员作为案头速查资料。

1. 从一份“用友数据库表名.doc”说起:它到底能帮你解决什么

手里拿到一份《用友数据库表名.doc》,多数人的第一反应是“这不就是一张对照表吗”。真到项目上你会发现,它其实是排查问题的入口:客户说某张单据金额不对,你要顺着单据号找到主表、明细表、辅助表;二开要加字段,你得先确认目标表有没有被其他模块引用;做数据同步,你得先分清哪些表是业务主表、哪些是临时表、哪些是视图。用友 U8、T+、U9 cloud、BIP 这些产品线底层都跑在关系型数据库上,SQL Server、Oracle、达梦、金仓都有实际部署,表名文档就是你在这些库之间来回切换时的“地图”。这份文档本身不会告诉你字段含义、关联关系和更新时机,它只给名字,剩下的靠你去数据库里验证。这篇笔记就按“拿到文档之后怎么用”来讲:怎么把表名变成可查询的资产、怎么定位一张单据背后的表、怎么避开那些看起来像业务表其实是中间表的坑。适合做用友二次开发、数据集成、报表取数、运维排查的同行,新手能照着步骤走,熟手可以对照参数和边界。

2. 把表名文档变成可查询资产:从 doc 到数据字典

2.1 先判断文档覆盖的是哪条产品线

用友不同产品线的表命名规则差异很大,拿到文档第一步不是急着导入,而是确认它对应哪个版本、哪个模块。U8 的表名常见rdrecord、rdrecords、SaleBillVouch这类带业务缩写的前缀;T+ 更多用SA_、PU_、ST_这种模块前缀;U9 cloud 和 BIP 因为走的是元数据驱动,表名往往带UFIDA、UBF或者一串看起来像哈希的后缀。文档里如果混着多个产品线的表,直接拿去查会浪费大量时间。

我一般会先抽 20 到 30 个表名,在测试库执行一次存在性检查,确认哪些表在当前库真实存在。这一步能过滤掉文档里过时或跨版本的部分。下面这段 SQL 以 SQL Server 为例,查的是当前库中这些表是否存在以及大致行数,Oracle 和达梦把系统视图换成all_tables、user_tables即可。

-- 把文档里的表名整理成临时表或 IN 列表,逐条核对 SELECT t.name AS table_name, p.rows AS row_count, t.create_date, t.modify_date FROM sys.tables t JOIN sys.partitions p ON t.object_id = p.object_id AND p.index_id IN (0, 1) -- 0 堆表,1 聚集索引 WHERE t.name IN ( 'rdrecord', 'rdrecords', 'SaleBillVouch', 'SA_SaleOrder', 'PU_PurchaseOrder', 'ST_CurrentStock' ) ORDER BY p.rows DESC;

逻辑说明:sys.partitions里index_id为 0 或 1 的记录对应表的数据页,rows就是近似行数,比COUNT(*)快得多,适合大表快速摸底。参数上,IN列表就是文档里你关心的表名,建议分批放,一次别超过 200 个,否则语句解析本身会变慢。如果查出来某张表行数为 0 但文档标注是核心业务表,大概率是版本不对或者该模块没启用,先别往下做关联分析。

2.2 用系统视图补全字段和注释

表名文档通常只有表名,没有字段。真正干活时你需要字段名、类型、是否可空、默认值、注释。SQL Server 用sys.columns加sys.extended_properties,Oracle 用all_tab_columns加all_col_comments,达梦和金仓基本兼容 Oracle 那套。下面这段查的是指定表的字段清单和注释,注释字段在用友库里经常是空的,但只要有就优先看,它比字段名更接近业务含义。

-- SQL Server:查表字段、类型、可空、默认值、注释 SELECT c.name AS column_name, ty.name AS data_type, c.max_length, c.precision, c.scale, c.is_nullable, dc.definition AS default_value, ep.value AS column_comment FROM sys.columns c JOIN sys.types ty ON c.user_type_id = ty.user_type_id LEFT JOIN sys.default_constraints dc ON c.default_object_id = dc.object_id LEFT JOIN sys.extended_properties ep ON ep.major_id = c.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' WHERE c.object_id = OBJECT_ID('rdrecord') ORDER BY c.column_id;

逻辑说明:OBJECT_ID把表名转成对象 ID,避免字符串拼接;extended_properties里MS_Description是 SQL Server 存列注释的常见键名,用友部分版本会写,部分版本不写,查不到不代表字段没含义。参数上,max_length对nvarchar是字节数,实际字符数要除以 2,这个细节在写报表取数时经常导致截断。把这段查询结果和文档里的表名合并,你就得到了一份可检索的本地数据字典,后面所有排查都基于它。

2.3 建立表名到业务对象的映射索引

光有表名和字段还不够,你要能回答“销售订单在哪张表”“库存现存量在哪张表”。我的做法是建一张映射表,字段包括:产品线、模块、业务对象、主表名、明细表名、关联字段、备注。初始数据从文档和实际查询里来,后续每解决一个问题就补一条。下面是一个建表和插入示例,用 SQLite 或 MySQL 都能跑,方便本地维护。

-- 本地维护的业务对象到表名映射 CREATE TABLE uf_table_map ( id INTEGER PRIMARY KEY, product_line VARCHAR(32), -- U8 / T+ / U9 / BIP module_name VARCHAR(64), -- 销售 / 采购 / 库存 biz_object VARCHAR(64), -- 销售订单 / 采购入库单 main_table VARCHAR(128), detail_table VARCHAR(128), join_key VARCHAR(128), -- 主明细关联字段 remark VARCHAR(255) ); INSERT INTO uf_table_map (product_line, module_name, biz_object, main_table, detail_table, join_key, remark) VALUES ('U8', '销售', '销售订单', 'SaleBillVouch', 'SaleBillVouchs', 'SBVID', '主表存表头,明细存行'), ('U8', '库存', '现存量', 'ST_CurrentStock', NULL, NULL, '按仓库+存货维度'), ('T+', '采购', '采购订单', 'PU_PurchaseOrder', 'PU_PurchaseOrderDetail', 'ID', '注意逻辑删除标记');

逻辑说明:join_key是主表和明细表的关联字段,用友很多模块用ID或AutoID,但销售订单这类用SBVID,不统一,必须逐模块确认。remark里记的是容易踩的坑,比如逻辑删除标记、多组织隔离字段。这张映射表不需要一次建全,先覆盖你当前项目涉及的 10 到 20 个业务对象,用起来之后再扩。有了它,下次有人问“现存量在哪”,你直接查表,不用再翻文档。

3. 定位一张单据背后的表:从界面到 SQL 的完整链路

3.1 从单据号反查主表的通用思路

客户给一个单据号,你要找到它落在哪张表。用友界面上的单据号通常对应主表的一个编号字段,U8 里常见cCode、cVouchCode,T+ 里常见Code、BillNo。但直接拿单据号去全库搜字段名不现实,我的做法是先按模块缩小范围,再在候选主表里查。下面这段 SQL 演示的是在 U8 销售订单里按单据号反查,SaleBillVouch是主表,cCode是订单号字段。

-- 按单据号反查销售订单主表 SELECT SBVID, cCode, cCusCode, dDate, cMemo FROM SaleBillVouch WHERE cCode = 'SO20240115001';

逻辑说明:SBVID是主键,后面关联明细要用它;cCusCode是客户编码,dDate是单据日期。参数上,cCode的值要和界面完全一致,包括前后空格,用友部分版本会补零,查不到时先LIKE '%SO20240115001%'试一次。如果这张表查不到,别急着换表,先确认单据类型是不是走了另一张表,比如退货单、调拨单往往有独立主表。

3.2 主表与明细表的关联查询

找到主表后,明细在SaleBillVouchs,关联字段是SBVID。下面这段把表头和行一起查出来,同时带上存货编码和数量。

-- 主表 + 明细表关联 SELECT m.cCode AS 订单号, m.dDate AS 单据日期, d.cInvCode AS 存货编码, d.iQuantity AS 数量, d.iTaxUnitPrice AS 含税单价, d.iSum AS 金额 FROM SaleBillVouch m JOIN SaleBillVouchs d ON m.SBVID = d.SBVID WHERE m.cCode = 'SO20240115001' ORDER BY d.AutoID;

逻辑说明:JOIN条件必须是主键到外键,用友明细表里SBVID是外键,AutoID是行号,排序用它保证行序和界面一致。参数上,iQuantity和iSum在很多版本里是乘以了数量精度的整数,比如实际数量 10 存成 1000000,具体倍数看iQuantity的字段精度设置,直接展示会差几个数量级,这是报表取数最常见的翻车点之一。

3.3 用扩展字段表处理自定义项

用友单据上经常有自定义项,这些字段不在主表里,而在扩展表。U8 里常见SaleBillVouch_Extra或者按自定义项编号拆成多张表。查的时候要先确认自定义项定义在哪,再关联。下面这段演示关联扩展表取自定义项。

-- 关联扩展表取自定义项(表名以实际为准) SELECT m.cCode, d.cInvCode, e.cDefine1, e.cDefine2 FROM SaleBillVouch m JOIN SaleBillVouchs d ON m.SBVID = d.SBVID LEFT JOIN SaleBillVouch_Extra e ON m.SBVID = e.SBVID WHERE m.cCode = 'SO20240115001';

逻辑说明:用LEFT JOIN是因为扩展表不一定每单都有记录,用INNER JOIN会丢单。参数上,cDefine1到cDefineN对应自定义项 1 到 N,具体哪个自定义项是什么含义,要去单据模板里看,不能凭字段名猜。如果扩展表不存在,说明该版本把自定义项直接加在主表上了,回到字段清单里找cDefine开头的列。

4. 跨库迁移与同步:表名文档在数据集成里的用法

4.1 先分清业务主表、临时表和视图

做数据同步时,最怕把临时表当业务表同步过去。用友库里有一批表名看起来很像业务表,实际是中间过程表,比如temp_开头、_bak结尾、或者带日期后缀的。同步前先跑一遍分类查询,把表和视图分开,把疑似临时表标出来。

-- SQL Server:列出表和视图,标记疑似临时表 SELECT name AS object_name, type_desc, CASE WHEN name LIKE 'temp%' OR name LIKE '%_bak' OR name LIKE '%_tmp' THEN '疑似临时' ELSE '常规' END AS flag FROM sys.objects WHERE type IN ('U', 'V') ORDER BY flag, name;

逻辑说明:type为U是用户表,V是视图,视图一般不参与同步,除非对方明确要。参数上,LIKE规则按你实际环境补,有些项目用tmp_前缀,有些用_his后缀。把结果导出,和表名文档对照,文档里没有但库里有的表,大概率是二次开发加的或者系统临时表,同步时要单独决策。

4.2 用主键和更新时间做增量同步

全量同步只适合首次,后续要走增量。用友很多业务表有ts时间戳字段或者dModifyDate修改日期,但并不是每张表都有。没有更新时间字段的表,只能用主键范围或者全量比对。下面这段演示按修改时间做增量抽取。

-- 按修改时间增量抽取(字段名以实际为准) SELECT SBVID, cCode, cCusCode, dDate, dModifyDate FROM SaleBillVouch WHERE dModifyDate >= '2024-01-15 00:00:00' AND dModifyDate < '2024-01-16 00:00:00';

逻辑说明:时间范围用左闭右开,避免边界重复。参数上,dModifyDate如果为空,说明该表不记录修改时间,要换策略。增量同步还要考虑删除,用友多数业务表是逻辑删除,用bDelete或iStatus标记,物理删除少,同步时要带上删除标记字段,否则对方库会残留已删数据。

4.3 跨数据库类型时的字段映射

源库是 SQL Server,目标库是达梦或金仓时,字段类型要映射。下面这张表是我常用的对照,具体以目标库版本为准。

源类型(SQL Server)目标类型(达梦/金仓)注意
intINT直接对应
bigintBIGINT直接对应
nvarchar(n)VARCHAR(n)字符数按目标库定义,注意中文
datetimeTIMESTAMP精度可能不同
decimal(p,s)DECIMAL(p,s)精度一致
bitTINYINT/BOOLEAN看目标库支持

逻辑说明:nvarchar转VARCHAR时,如果目标库按字节算长度,中文会占 2 到 3 字节,字段长度要放大。参数上,datetime转TIMESTAMP后,毫秒精度可能丢失,对账时会出现时间差 1 秒的情况,同步任务里要做容差。跨库同步前先用小批量数据跑通,再放全量。

5. 避坑与排查:表名文档用错时的典型翻车现场

5.1 现象:按文档查表提示对象不存在

原因:文档对应的是另一个版本或另一个产品线,或者表在另一个数据库实例里。用友 U8 常见多账套、多年度库,表名相同但库不同。解决:先确认当前连接的库名和账套,再用sys.databases或v$database核对;跨年度查数据要切库,不能在一个连接里跨库 JOIN 不同年度的表。

5.2 现象:查出来的数量和界面不一致

原因:数量字段存的是放大后的整数,或者过滤条件漏了逻辑删除、多组织隔离。解决:先查字段精度设置,确认放大倍数;再补bDelete = 0或iStatus <> 2这类条件;多组织版本还要加cOrgCode或iOrgID过滤。这三个条件漏一个,数量就对不上。

5.3 现象:主明细关联后行数变多

原因:明细表里同一主键有多条记录,或者关联字段选错,比如用ID关联了AutoID。解决:先单独查明细表按主键分组计数,确认是否一对多;再核对关联字段类型和含义,用友里ID、AutoID、SBVID混用很常见,必须逐表确认。

5.4 现象:同步任务跑一段时间后目标库数据重复

原因:增量字段选错,比如用了创建时间而不是修改时间,或者时间范围边界重复。解决:改用修改时间字段,范围左闭右开;目标库对主键做唯一约束,重复插入时用MERGE或INSERT ... ON DUPLICATE KEY UPDATE兜底。

5.5 现象:自定义项取不到值

原因:自定义项不在主表,在扩展表,或者自定义项编号和字段名不对应。解决:先去单据模板确认自定义项定义,再找对应扩展表;如果扩展表不存在,回主表找cDefine字段。不要凭cDefine1就认为是自定义项 1,部分版本编号从 0 开始。

6. 把表名文档用成长期资产:我的维护习惯和一条验证技巧

表名文档最大的问题不是内容少,而是会过时。打补丁、上模块、二开加表,文档不会自动更新。我的习惯是每解决一个排查问题,就往本地映射表里补一条记录,字段包括产品线、模块、业务对象、主表、明细表、关联字段、坑点。补的时候顺手跑一次验证查询,确认表还在、字段还在、关联关系还成立。下面这段是我常用的验证脚本,一次检查映射表里所有记录的主表和明细表是否可访问。

-- 验证映射表里的表和关联字段是否仍然有效 SELECT m.biz_object, m.main_table, m.detail_table, m.join_key, CASE WHEN OBJECT_ID(m.main_table) IS NULL THEN '主表缺失' ELSE '主表正常' END AS main_status, CASE WHEN m.detail_table IS NOT NULL AND OBJECT_ID(m.detail_table) IS NULL THEN '明细表缺失' ELSE '明细表正常' END AS detail_status FROM uf_table_map m;

逻辑说明:OBJECT_ID返回 NULL 说明表不存在,可能是版本升级后改名或删除。参数上,detail_table允许为空,因为有些业务对象只有主表。跑完把异常记录标出来,人工确认是废弃还是改名,改名的更新映射表,废弃的加备注保留,不要直接删,历史项目可能还要查。

另一个习惯是给每张核心表记一条“最小验证 SQL”,比如销售订单就是按单据号查主明细,库存就是按仓库加存货查现存量。下次怀疑数据问题时,先跑最小验证 SQL,确认表本身有数据,再去查业务逻辑。这个习惯帮我省掉很多“以为是数据问题其实是表选错”的时间。表名文档只是起点,真正值钱的是你围绕它积累的映射关系和验证脚本。希望帮到你。

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

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

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

立即咨询