ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

U9 BP数据怎么查?用友U9业务伙伴查询的三种实用方法

U9 BP数据怎么查?用友U9业务伙伴查询的三种实用方法 做U9二次开发这几年总会被业务方问到同一个问题U9里到底怎么查BP数据这里的BP不是Back Propagation神经网络而是Business Partner也就是业务伙伴。在U9里它统一涵盖了客户、供应商甚至内部部门。之前我接到一个需求要把三百多家客户的联系人和信用额度按地区批量导出来用系统自带功能点得手酸不说列表还经常转圈卡死。后来我从界面、接口、数据库三个层面把U9的BP查询路子整个趟了一遍才算真正摸清。这篇就讲清楚我摸索出来的BP查询方法对搞U9运维和二次开发的兄弟应该能省不少劲。1. 先搞清楚U9里的BP是什么查询场景有哪些1.1 BP概念和U9的数据模型U9是典型的SOA架构ERP把企业的主数据统一建模。BP也就是业务伙伴在这个模型里是一个很核心的大头。客户、供应商、经销商、内部组织等都被纳入了BP这个逻辑实体内。这样做的好处是销售、采购、财务模块引用主数据时不需要区分到底是客户还是供应商统一用BP编码就行了。但坏处也很明显对业务人员来说他们习惯分客户档案、供应商档案U9却在一个大表里存标准界面的查询逻辑就又绕又慢。实际在数据库层面BP主数据往往存放在以Base_BP为前缀的若干张表里。主表存最基本的编码、名称、状态扩展表存联系人、地址、银行账号分类表存客户/供应商的类型还有信用、价格等衍生表。我第一次做这个需求时光确认表对应关系就花了一上午。所以后面我会专门讲怎么用工具快速找表而不是靠猜。1.2 业务中最常见的BP查询需求在一线碰到的BP查询无非这么几大类。第一类是模糊搜名称含某关键词比如查所有名字带“科技”的客户。第二类是按归属关系过滤比如某业务员名下有哪些分销商。第三类是组合条件比如华东区的、信用等级为A的、最近一年有交易的供应商。第四类是反向查询即通过销售订单或采购单据反查BP的联系人、税号、付款条件。这些需求听起来很简单但U9标准界面的查询往往只能处理前两类第三类、第四类就需要动心思了。尤其是需要导出大量字段时标准功能一次最多导出明细列表里显示的那些列想要的联系人手机号、开户行账号可能根本不在列表里于是就得想别的办法。1.3 为什么不能指望标准查询我见过很多实施顾问给业务人员的培训就是点放大镜输入编码点确定。这套流程在几十条数据时没问题一旦数据量到了几十万标准查询的缺点就全暴露了。U9标准列表查询默认会读取单据模板的栏目配置很多隐藏字段即使没显示在界面上也会被SELECT进临时表导致查询缓慢。而且多条件过滤用的是模糊匹配不走索引的情况时有发生。另外标准查询的按编码模糊会给业务人员示好但后台可能生成了LIKE %xxx%这玩意儿在SQL Server里基本等于全表扫描。数据量一大卡上几十秒很正常。所以在实际项目里我发现与其天天吐槽界面慢不如直接给业务方做一个定制查询页面这也就引出了下面要介绍的几种更实用的方法。2. 方法一压榨U9标准界面至少解决80%日常查询2.1 用高级筛选替代简单放大镜大多数用户只知道U9列表界面左上角有个简单查询框其实在业务伙伴-客户档案列表里工具栏上还有一个高级筛选入口只是藏得深。点开之后就可以设置多个字段条件比如客户分类等于重点客户并且所属地区包含华东并且信用等级等于A。这些条件之间是并且的关系满足大多数组合过滤的场景。具体操作上先打开客户档案列表点击工具栏上的高级查询按钮有些版本叫筛选查询条件在弹出的窗口里选择字段名、操作符等于、包含、大于等输入值然后点击添加条件。多个条件会形成一个条件组还可以设置条件组间的并且/或者关系。我之前给业务人员培训时专门把常用条件组合保存成方案他们后续点一下就能复用。2.2 把常用查询保存成个人方案高级筛选窗口里填完一堆条件之后底部有保存方案按钮。建议以业务语义命名比如华东大客户信用A级、近三个月活跃供应商。保存后下次在列表界面的方案下拉框里直接选择系统自动带出条件。这个功能很多老用户用了五六年都不知道其实对提高效率特别有帮助。此外U9的列表界面支持把当前查询结果输出到Excel。在列表上方的导出图标里选当前页或全部数据如果数据量不大。导出格式可以选xls或xlsx。这里有个小坑如果列表本身因为性能问题没显示全部数据导出的也只是当前加载的数据。所以导出前最好先执行一次高级查询缩小范围。2.3 标准查询的局限和替代思路即便用上高级筛选依然解决不了按联系人手机号搜索客户这样的冷门条件因为标准筛选面板里根本没有联系人手机号这个字段。这时候就得考虑二开或者直接走数据库。还有某些U9版本的权限控制较严高级筛选里能选到的字段受制于当前用户的数据权限如果发现字段找不到多半是因为没有分配可见字段权限。标准界面作为日常兜底工具还是够用的。我有一个习惯凡是业务方说这个查询条件界面上弄不出来的我第一反应不是急着写代码而是先打开高级筛选面板看看往往他们只是不会用。真的弄不出来了再上后面的重武器。3. 方法二通过U9接口做精准BP查询适合需要程序集成3.1 认识U9的BP查询服务和SV代理U9把业务操作封装成服务BP的查询也有对应的标准服务通常叫做BPQuery或者QueryBusinessPartner。在U9的二次开发架构里外部程序不能直接连数据库也不能直接碰业务逻辑而应该调用U9的服务代理SV。SV是一个部署在IIS上的中间层外部程序通过HTTP/HTTPSSOAP或.NET Remoting访问SVSV再去跟U9的应用服务器通信最后把结果返回。我们在项目里最常见的做法是先通过U9的管理控制台或者开发工具定位到BP查询服务查看它的输入输出参数。输入一般是一个BPQueryDTO里面包含查询条件编码、名称、ID、分类、状态等和一些分页配置。输出通常是一个DataSet或者对象列表里面包含了BP的主表字段和扩展字段。有了这个接口我们就能在自己的程序里像调用普通WebService一样去查BP了。3.2 用Java写一个BP查询调用示例我经常遇到企业里其他系统是Java写的要跟U9对接查BP。下面这段代码是我在项目里整理出来的简化示例核心是构造SOAP请求通过HTTP调用U9的SV服务解析返回内容。// BP查询请求参数 MapString, Object queryParams new HashMap(); queryParams.put(BPType, Customer); queryParams.put(BpCode, C%); // 编码模糊查询 queryParams.put(BpName, null); queryParams.put(State, 1); // 生效状态下 queryParams.put(PageIndex, 1); queryParams.put(PageSize, 100); // 将参数组织成SOAP Envelope String soapEnvelope buildSoapEnvelope(QueryBP, queryParams); // 通过HttpClient调用SV服务地址 HttpClient client HttpClient.newHttpClient(); HttpRequest request HttpRequest.newBuilder() .uri(URI.create(http://u9sv-server/U9Service/BPSV.svc)) .header(Content-Type, application/soapxml; charsetutf-8) .POST(HttpRequest.BodyPublishers.ofString(soapEnvelope)) .build(); HttpResponseString response client.send(request, HttpResponse.BodyHandlers.ofString()); // 解析SOAP响应中的DataSet String result parseSoapResult(response.body()); System.out.println(查到BP数据: result);实际项目里我们一般会用工具比如SoapUI先调通再生成客户端代理类代码会更简洁。调用接口时要特别注意U9的SV服务默认有会话和权限校验通常需要在HTTP头里带上身份票据或者设置Windows集成认证否则会报未授权。3.3 接口查询的性能和可靠性优化接口查询虽然灵活但性能受制于U9服务器本身。如果业务方要求的是一次性拉全量BP并同步到外部系统建议不要直接用查询接口一次取几十万条应使用U9提供的BP导出专用服务或者做分页循环。分页时用PageIndex配合PageSize每次取1000或2000条测试下来比一次性取出快得多而且不容易超时。还有一个容易踩的坑是货币、日期格式的转换。U9接口返回的日期往往是标准DateTime但SOAP序列化后可能带有时区信息解析不对会导致数据差一天。我的经验是在解析层统一转换成yyyy-MM-dd HH:mm:ss字符串再处理不要直接用对象类型去后续操作。3.4 什么时候该用接口什么时候不该用接口适合两种场景一是外部系统OA、BI需要实时查U9的BP数据二是二次开发页面需要和U9做事务联动比如在自定义表单里选择BP后要校验其信用额度。如果只是给业务人员多写几个查询报表完全没有必要用接口直接走数据库或者U9报表工具就行接口的维护成本高而且U9升级时接口不保证完全兼容。我自己经历过一次U9升级从2017版升到2022版旧版本里能直接调用的某个BP查询服务在新版本里被标记为废弃不得不改代码。所以开发接口前一定要先去U9的服务管理里确认版本支持项目文档里也要记录所基于的U9版本否则过半年回头改会很难受。4. 方法三直连数据库一条SQL搞定复杂BP查询4.1 用数据库监控工具找到U9界面背后的SQL如果不想跟接口较劲最直接的方法是连U9的数据库查。很多项目里允许只读账号访问U9的数据库这种模式做报表和临时查询非常高效。问题是U9的数据表这么多怎么知道哪张表存的是BP呢我的土办法是用SQL Server Profiler如果是Oracle就用审计功能跟踪一次U9界面的BP查询把实际执行的SQL捞出来。操作步骤并不复杂先启动SQL Profiler新建跟踪选择事件SQL:BatchCompleted和RPC:Completed过滤DatabaseName为U9的库然后在U9界面里执行一次客户档案查询。跟踪停止后搜索SQL语句里的From关键词很快就能看到主表名和关联的表。比如常见的是Base_BP_Main关联Base_BP_Extend其中客户类型过滤会关联Base_BP_Customer或分类表。用这个办法不止能查BP任何U9界面的查询都能用它顺藤摸瓜找到底层表。找到表之后我们就可以抛开界面直接写SQL了。4.2 BP核心表结构的通用套路根据我在多个U9项目中的观察BP相关的表一般以Base_BP开头核心是主表和扩展表。主表Base_BP_Main存储BP编码、名称、状态、简称、所属组织等最基础字段BP_ID是其主键。扩展表Base_BP_Extend存储联系信息、地址、电话、邮箱、税务登记号等通过BP_ID关联主表。分类表Base_BP_Category存储BP的分类客户/供应商/内部通过BP_ID与分类ID关联。银行信息Base_BP_Bank存储开户行、账号等。编码规则Base_BP_CodeRule或类似表控制自动编号。具体表名可能因U9版本不同有差异但套路是统一的先找主表再通过外键找扩展表和子表。如果忘记了可以用系统的数据库关系图或查询系统表sys.foreign_keys来发现关联关系。4.3 一个可复用的BP查询SQL模板下面这段SQL是我经常改一改就用的通用模板实现了按编码、名称、分类、组织、状态和关键联系人过滤-- 查询生效中的、名称含科技的客户型BP并带出联系人信息 SELECT main.BP_ID, main.BP_Code AS 编码, main.BP_Name AS 名称, main.BP_State AS 状态, ext.Contact_Person AS 联系人, ext.Contact_Mobile AS 手机号, ext.EMail AS 邮箱, c.Category_Name AS BP分类 FROM Base_BP_Main main LEFT JOIN Base_BP_Extend ext ON main.BP_ID ext.BP_ID LEFT JOIN Base_BP_Relation rel ON main.BP_ID rel.BP_ID -- 业务伙伴分类关系 LEFT JOIN Base_BP_Category c ON rel.Category_ID c.Category_ID WHERE main.BP_State 1 AND main.BP_Name LIKE N%科技% AND c.Category_Name N客户 AND (ext.Contact_Mobile LIKE N%138% OR ext.Contact_Person IS NOT NULL) ORDER BY main.BP_Code;注意U9数据库如果是中文环境条件值记得加上N前缀避免中文乱码。这种大宽表的LEFT JOIN在数据量很大时会慢最好先分页或加几个临时表。为了性能和简洁我更建议将查询拆成两步第一步从主表查出符合条件的BP_ID列表只查主表第二步再根据BP_ID去关联扩展表批量获取详细字段。这样每步都能走主键索引避免了大表JOIN。4.4 数据库直连必须遵守的规矩数据库直连不是让你随便写改和删只允许SELECT权限。我给团队定了几条铁律一是严禁裸奔的SELECT *一定要列出需要的字段否则带宽和内存都会爆二是查询必须带条件严禁不带WHERE的全表扫描三是大结果集必须分页建议用OFFSET FETCH或ROW_NUMBER()四是查询高峰期比如月末结账避开执行大查询防止锁表。如果只是临时查一次开一个查询窗口跑完就关。如果有长期固定的BP查询需求建议建一个视图把常用的关联逻辑写进去这样应用层只需要SELECT * FROM V_BP_Query WHERE 编码 LIKE %xx%就行。视图在U9升级后可能需要重建所以要放到脚本管理里做版本控制。5. 常见问题与排查技巧5.1 查询出来数据与U9界面不一致这个问题很坑。明明在数据库查询SQL返回的数据和U9界面上看到的同一BP记录对不上。最常见的原因是U9有组织隔离和数据权限。同一个BP在不同的Org组织下可能有不同的属性值数据库里存的是所有组织的值但U9界面默认按当前登陆人所属组织过滤。排查时先看SQL条件里有没有Org_ID或OrgCode字段加上后再查。还有一个原因是数据缓存。U9某些主数据查询走缓存界面看到的是缓存中的旧值。这种场景下界面刷新或重启应用服务器就能解决。我在项目里遇到过两次一度以为是SQL写错了最后发现是应用服务器缓存了将近一天的旧数据。5.2 数据库里找不到对应表或字段如果你用的是精简版的U9数据库可能部分模块的表被删减了或者因为版本差异表名带上了前缀后缀。比如有的版本叫Base_BP_Main有的叫Base_BP_Master还有的可能叫T_Base_BP_Info。遇到这种情况别急用数据库自带的查看依赖关系或者查一下INFORMATION_SCHEMA.TABLES表名中包含BP%的表基本上能定位。SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE %BP% ORDER BY TABLE_NAME;用这个SQL把全库包含BP的表捞出来再和第一步抓到的SQL对比很快能找到。实在不行去U9的元数据仓库或者开发工具里找实体定义那是最权威的。5.3 接口调用超时或返回慢如果通过SV调用BP查询总是超时先检查是不是查询条件太宽泛。比如BP_Name LIke %%这种空条件会把整个BP表的数据取回来不超时才怪。解决办法是强制分页和加必选条件比如要求至少传入编码前缀或分类。还可以调整U9服务端的超时时间IIS里对SV站点设置脚本超时为120s或更长但治标不治本根子上还是要限速。我在一个项目里用接口一次性拉了6万条BP进行缓存同步结果跑了四十分钟直接超时。后来改成每次取3000条后台循环不到十分钟就全部拿完了。所以批量取数务必采用分页游标模式。5.4 权限与安全合规提醒BP数据涉及客户和供应商的商业信息怎么查都不为过但查询结果不能随意扩散。无论是用接口还是直连数据库都建议用只读账号并在代码里记录日志保留查询人、查询时间、查询条件。我见过有公司开发人员为了方便直接用了sa账号连数据库做定时导出后来闹出了事故。该走审计流程的必须走账号权限能最小化就最小化这一点无论业务多着急都不能省。6. 实际项目里的几条心得最后聊几句我在多个项目里攒下的经验。第一个心得是别一上来就写代码。先跟业务方确认他们要的到底是查出来看还是查出来用。如果是看标准界面加高级筛选足以如果是要用再评估是走接口还是走数据库。很多项目原本只需要一个Excel模板结果被开发成了独立系统开销大不说业务方还不满意因为功能太重了。第二个心得是数据库直接写SQL是效率最高的查找方式但也是风险最高的。我通常会先花半小时用SQL Profiler跟踪一次界面操作把表结构关系摸清楚然后才敢写SQL。这样预判到的坑比事后排查少很多。第三个心得是无论是写接口还是写SQL一定要留一个可配置的查询条件类。BP查询需求日后一定会变字段的增加和筛选逻辑的调整是必然的。把条件参数化设计好后面维护会省很多事。如果你也正被U9的BP查询折磨不妨按我上面说的三步走先打开高级筛选再试接口最后直连数据库。大部分需求都能在这三层里找到合适解法。真要是遇到连SQL都搞不定的场景大概率就是权限或数据架构的问题了那就需要更细致的排查了。
返回列表