简介:这份资源是PeopleSoft Application Engine的中文版官方文档,面向PeopleSoft开发人员、人力系统实施顾问及需要维护批量业务流程的技术人员。Application Engine作为PeopleSoft后台工作流的核心组件,承担数据更新、报表生成、接口同步等批量处理任务,文档通过深度翻译帮助中文用户理解其编程模型与运行机制。压缩包内仅含1个PDF文件,大小约2.25MB,内容源自Enterprise PeopleTools 8.50 PeopleBook,涵盖应用引擎概述、实施方法、程序元素(栏目、阶梯、行动)、Meta-SQL、并发执行、错误恢复、日志记录与性能优化等章节,并附有Oracle许可限制、保修声明及危险应用通知等法律条款。目前已有345人学习。读者可借助该文档掌握Application Engine程序的创建与配置流程,理解其与PeopleCode、Job、Process Scheduler的协同方式,并获取批量数据处理与定时任务设计的排错思路,适合作为日常开发与系统维护的案头参考。1. 从一份 2009 年的 PeopleBook 说起:AE 中文文档到底能解决什么如果你正在维护一套 PeopleSoft 人力系统,大概率遇到过这种场景:Process Scheduler 里某个 AE 程序跑了一半卡住,日志只给一行含糊的 SQL 错误,翻官方英文文档又全是术语堆叠,查一个%AeProgram的用法要来回跳三四个页面。这份《PeopleSoft Application Engine 中文文档》对应的就是 Enterprise PeopleTools 8.50 的 PeopleBook,SKU 为 pt850pbr0,内容覆盖从「开始使用应用引擎」到 Meta-SQL 参考的完整章节。它不是教程,也不是视频课,而是一份把官方英文手册逐章翻译过来的参考文档,适合已经上手 PeopleSoft、需要快速定位 AE 程序元素定义和 Meta-SQL 语法的开发者。换句话说,它解决的不是「AE 是什么」,而是「这个参数到底填什么、这个动作类型什么时候用」。2. 拆开 AE 程序结构:Section、Step、Action 三层到底怎么落2.1 程序元素的层级关系与定义视图Application Engine 程序的骨架是三层结构:Section(章节)→ Step(阶梯)→ Action(行动)。文档第二章把这个层级讲得很清楚,但真正上手时容易混淆的是「定义视图」和「程序流视图」的区别。定义视图是树状结构,适合批量调整属性;程序流视图是流程图式展示,适合看执行顺序。我一般习惯先在定义视图里把 Section 建好,再切到程序流视图检查 Step 的排列是否符合预期。每个 Section 可以设置自己的属性,比如是否启用、是否并行执行。Step 是执行的最小调度单位,一个 Step 里可以放多个 Action,Action 按顺序执行。这里有个容易翻车的地方:Step 的属性里有一个「On Error」选项,决定出错后是继续下一步还是中止整个程序。默认值不一定符合你的业务预期,尤其是涉及批量更新时,选错了会导致部分数据已提交、部分回滚。文档第三章详细列出了 Action 的类型:SQL、Do、PeopleCode、Call Section、Log Message、XSLT。每种 Action 有自己的属性面板,SQL Action 需要指定 SQL 类型(Select、Update、Insert 等),Do Action 需要指定是 Select、Fetch、When 还是其他。这些在文档里都有表格对照,但实际配置时最容易搞混的是 SQL Action 和 Do Action 的配合使用。2.2 用 State Record 传递状态:临时表与国家记录的选型State Record(状态记录)是 AE 程序里跨 Section、跨 Step 传递数据的核心机制。文档里叫「国家记录」,这个翻译有点生硬,但意思就是程序运行期间保存中间状态的记录。它本质上是一个 PeopleSoft 记录定义,可以基于物理表也可以基于临时表。选型时有个判断标准:如果程序是并发运行的,State Record 必须用临时表,否则多个实例会互相覆盖数据。文档在「为国家记录选择记录类型」一节里提到了这一点,但没有展开讲并发场景。我一般会这样处理:先确认这个 AE 程序会不会被多个 Process Scheduler 实例同时触发,如果是,State Record 对应的记录必须勾选「临时表」属性,并且要在 AE 程序属性里指定临时表实例数。设置 State Record 的步骤不复杂,但有几个参数容易漏:-- 在 AE 程序属性中指定 State Record -- 常见做法是在 PeopleTools 的 Application Engine 定义里 -- 找到「State Record」选项卡,填入记录名 -- 如果是临时表,还需要在「Temp Table」选项卡里 -- 指定实例数(通常设为 3 到 5,视并发量而定)逻辑说明:State Record 的名字必须是一个已存在的记录定义,不能临时创建。临时表实例数的含义是:每个并发实例分配一个独立的临时表副本,实例数决定了最大并发数。设得太少,高并发时会排队;设得太多,数据库里会多出一堆临时表,占用表空间。参数说明:实例数一般按「峰值并发数 × 1.5」估算。如果程序只在夜间跑一次,实例数设为 1 就够。另外,临时表的「记录类型」要选对,PeopleSoft 支持「临时表」和「非临时表」两种,前者在程序结束后自动清理数据,后者需要手动清理。2.3 批量插入与集合处理:为什么逐行处理是性能杀手文档第四章「制定高效的方案」里,最值得反复读的是「使用集合处理」和「避免逐行处理」这两节。AE 程序最常见的性能问题就是:用 PeopleCode 循环逐行读取数据,再逐行更新。这种写法在数据量小的时候看不出问题,一旦上万行就会慢得离谱。集合处理的核心思路是用 SQL 的Set操作代替逐行Fetch。具体做法是:在 SQL Action 里写一条UPDATE或INSERT ... SELECT语句,一次性处理整批数据,而不是在 PeopleCode 里循环。文档里给了一个例子,大意是把一个 Section 的 SQL 类型设为Update,然后在 SQL 编辑器里写批量更新语句。我一般会这样改造一个逐行处理的程序:-- 改造前:逐行处理(伪代码) -- 在 PeopleCode Action 里循环 Fetch 每一行 -- 然后逐行执行 UPDATE -- 改造后:集合处理 -- 在 SQL Action 里直接写: UPDATE PS_EMPLOYEE_TBL A SET A.STATUS = 'A' WHERE A.EMPLID IN ( SELECT B.EMPLID FROM PS_JOB B WHERE B.EFFDT = (SELECT MAX(C.EFFDT) FROM PS_JOB C WHERE C.EMPLID = B.EMPLID) AND B.ACTION = 'HIR' )逻辑说明:这条 SQL 一次性把所有符合条件的雇员状态更新为A,不需要在 PeopleCode 里循环。AE 的 SQL Action 会把整条语句交给数据库执行,数据库的批量处理能力远强于逐行 Fetch。参数说明:EFFDT的子查询是为了取最新生效日期,这是 PeopleSoft 人力系统里常见的「取最新记录」模式。注意IN子查询的性能,如果PS_JOB数据量很大,建议改成EXISTS或JOIN。另外,批量更新前一定要在测试环境验证 SQL 的WHERE条件,避免误更新。文档还提到了「使用批量插入」的技巧:如果目标表是空表或可以追加,用INSERT ... SELECT比逐行插入快一个数量级。但要注意,批量插入不会触发 PeopleCode 的SaveEdit和SavePreChange事件,如果业务逻辑依赖这些事件,就不能用批量插入。3. Meta-SQL 与 PeopleCode 的配合:什么时候用哪个3.1 Meta-SQL 的常用占位符与展开规则Meta-SQL 是 AE 程序里特有的 SQL 扩展,用%开头的占位符表示。文档第五章列出了完整的 Meta-SQL 参考,从%Abs到%AeStep都有。实际开发中最常用的几个是:Meta-SQL用途常见场景%AeProgram展开为当前 AE 程序名日志记录、错误信息%AeSection展开为当前 Section 名日志记录%AeStep展开为当前 Step 名日志记录%DateIn日期格式转换跨数据库日期处理%DateOut日期格式转换跨数据库日期处理%Table展开为记录对应的物理表名动态 SQL%SelectAll展开为记录的所有字段动态查询%Table和%SelectAll在写动态 SQL 时特别有用。比如你要写一个通用的查询,不想硬编码表名,就可以用%Table(record_name)。但要注意,Meta-SQL 是在 AE 程序编译时展开的,不是运行时,所以不能用在动态拼接的 SQL 字符串里。%DateIn和%DateOut是跨数据库兼容的关键。PeopleSoft 支持多种数据库,不同数据库的日期格式不一样,直接用字符串拼日期会翻车。我一般会在所有涉及日期的 SQL 里都用%DateIn包一层:-- 不推荐:硬编码日期格式 SELECT * FROM PS_EMPLOYEE_TBL WHERE HIRE_DT > '2024-01-01' -- 推荐:用 Meta-SQL 转换 SELECT * FROM PS_EMPLOYEE_TBL WHERE HIRE_DT > %DateIn('2024-01-01')逻辑说明:%DateIn会把字符串按当前数据库的日期格式转换成日期类型,避免因数据库差异导致的格式错误。%DateOut则相反,把日期类型转成字符串。参数说明:%DateIn的参数是一个字符串,格式必须是YYYY-MM-DD。如果传入的格式不对,AE 程序会在编译时报错。另外,%DateIn只能用在 SQL Action 里,不能用在 PeopleCode 里。3.2 PeopleCode 在 AE 中的调用时机与限制PeopleCode 在 AE 程序里是通过 PeopleCode Action 调用的。文档第五章「在应用引擎程序中使用PeopleCode」一节里,最关键的一句话是:PeopleCode Action 的执行上下文和在线页面不一样,很多在线可用的函数在 AE 里不可用。具体来说,AE 里的 PeopleCode 不能直接访问组件缓冲区(Component Buffer),因为 AE 没有组件上下文。如果你在 PeopleCode 里写了GetRowset或GetRecord,运行时会报错。正确的做法是用SQL对象或Record对象直接操作数据库。另一个限制是CommitWork函数。文档里专门有一节讲「使用CommitWork函数」,大意是 AE 程序默认在每个 Step 结束后自动提交,但如果你的程序需要手动控制提交点,可以在 PeopleCode 里调用CommitWork()。不过要注意,频繁提交会影响性能,而且一旦提交,回滚就回不去了。我一般会这样处理提交策略:如果程序是批量更新,且更新逻辑可以分批,就在每个 Section 结束后提交一次;如果更新逻辑必须全部成功或全部失败,就关掉自动提交,在程序最后手动提交。关掉自动提交的方法是在 AE 程序属性里把「Commit」选项设为「After Step」或「After Section」,具体选哪个看业务需求。3.3 同步在线调用 AE 程序的注意事项文档第五章提到了「对应用引擎程序进行同步在线调用」,这是一个容易被忽略但很有用的功能。默认情况下,AE 程序是通过 Process Scheduler 异步执行的,但有些场景需要同步执行,比如用户点击按钮后立即返回结果。同步调用的方法是在 PeopleCode 里用CallAppEngine函数:/* 同步调用 AE 程序 */ Local string &result; &result = CallAppEngine("MY_AE_PROGRAM", &stateRecord); /* 检查返回状态 */ If &result = "Success" Then /* 处理成功逻辑 */ Else /* 处理失败逻辑 */ End-If;逻辑说明:CallAppEngine会同步执行指定的 AE 程序,并返回执行结果。&stateRecord是一个 State Record 的引用,用于传递参数和接收返回值。参数说明:第一个参数是 AE 程序名,必须是已定义的程序。第二个参数是 State Record,类型必须是AppEngine支持的记录类型。注意,同步调用会阻塞当前线程,如果 AE 程序执行时间较长,用户界面会卡住,所以只适合短时间运行的逻辑。4. 避坑与排查:AE 程序最常见的五类翻车现场4.1 现象:程序跑完了但数据没更新原因:最常见的原因是 SQL Action 的Commit设置不对。AE 程序默认在每个 Step 结束后自动提交,但如果 Step 的属性里把Commit设成了Never,或者程序属性里关掉了自动提交,数据就不会落库。解决:检查 AE 程序属性的「Commit」选项,确认是After Step还是After Section。如果是手动提交模式,确认 PeopleCode 里有没有调用CommitWork()。另外,检查 SQL Action 的ReUse属性,如果设成了ReUse,Statement 会被缓存,可能导致后续执行时用了旧的绑定变量。4.2 现象:State Record 数据被覆盖原因:多个并发实例共用了同一个 State Record,且没有启用临时表。AE 程序在 Process Scheduler 里可以并发触发,如果 State Record 基于物理表,实例 A 写入的数据会被实例 B 覆盖。解决:把 State Record 对应的记录定义改成临时表,并在 AE 程序属性里设置足够的临时表实例数。临时表的实例数决定了最大并发数,设少了会排队,设多了会占用表空间。我一般按「峰值并发数 + 2」来设。4.3 现象:Meta-SQL 展开后 SQL 语法错误原因:Meta-SQL 占位符用在了不支持的位置。比如%Table只能用在FROM子句里,不能用在SELECT列表里。或者%DateIn的参数格式不对,导致展开后的 SQL 里出现了非法日期字符串。解决:在 AE 程序的「SQL 预览」功能里查看展开后的 SQL。PeopleTools 提供了一个 SQL 预览窗口,可以看到 Meta-SQL 展开后的实际语句。如果预览报错,说明占位符用法有问题。另外,注意%Table的参数必须是记录名,不是表名。4.4 现象:PeopleCode Action 报「找不到记录」原因:AE 里的 PeopleCode 没有组件上下文,不能用GetRecord或GetRowset直接访问页面上的记录。如果代码里写了这类函数,运行时会报「Record not found」或「Rowset not found」。解决:改用CreateRecord或SQL对象直接操作数据库。比如要读取一条记录,可以用SQL对象执行SELECT,然后把结果赋给变量。如果必须用记录对象,用CreateRecord(record_name)创建一个独立的记录实例,而不是从组件缓冲区获取。4.5 现象:程序执行时间过长,Process Scheduler 超时原因:逐行处理导致性能瓶颈,或者 SQL 没有走索引。AE 程序的默认超时时间由 Process Scheduler 的配置决定,如果程序执行时间超过阈值,会被强制终止。解决:把逐行处理改成集合处理,用UPDATE ... SELECT或INSERT ... SELECT代替循环。检查 SQL 的执行计划,确认WHERE条件里的字段有索引。如果程序确实需要长时间运行,可以在 Process Scheduler 里调整超时时间,但更好的做法是优化 SQL。另外,AE 程序的「Step」属性里有一个「On Error」选项,如果设成了Abort,一旦出错整个程序会立即终止,不会继续执行后续 Step。5. 进阶技巧:用日志和调试工具定位 AE 程序问题5.1 开启 AE 程序的详细日志AE 程序的日志默认只记录 Section 和 Step 的起止时间,不记录 SQL 语句和绑定变量。要排查问题,需要开启详细日志。方法是在 Process Scheduler 的「Process Definition」里,把 AE 程序的「Log Level」设为Debug或Trace。# 在 Process Scheduler 的 Process Definition 里 # 找到 AE 程序对应的 Process # 把 Log Level 从默认的 "Info" 改成 "Debug" # 然后重新提交程序 # 日志文件会生成在 Process Scheduler 的日志目录下 # 文件名通常是 AE_MYPROGRAM_<ProcessInstance>.log逻辑说明:Debug级别会记录每个 Action 的执行详情,包括 SQL 语句和绑定变量。Trace级别更详细,会记录 PeopleCode 的每一行执行。日志文件的位置由 Process Scheduler 的配置决定,一般在$PS_HOME/appserv/prcs/<domain>/logs目录下。参数说明:日志级别越高,生成的日志文件越大,对性能的影响也越明显。建议只在排查问题时开启Debug,问题解决后改回Info。另外,日志文件会占用磁盘空间,定期清理是必要的。5.2 用 AE 程序的「测试模式」单步执行PeopleTools 提供了一个「测试模式」,可以在 Application Designer 里单步执行 AE 程序。这个功能在文档里没有详细讲,但实际排查问题时非常有用。开启方法是在 Application Designer 里打开 AE 程序,点击「Test」按钮,然后选择要执行的 Section 和 Step。测试模式下,可以逐 Step 执行,查看每个 Step 的输入输出。如果某个 Step 的 SQL 有问题,测试模式会直接报错,并显示展开后的 SQL 语句。我一般会在修改 AE 程序后,先用测试模式跑一遍关键 Section,确认没有语法错误再提交到 Process Scheduler。5.3 用 SQL 跟踪定位性能瓶颈如果 AE 程序的性能问题不在 SQL 本身,而在 PeopleCode 的循环逻辑,可以用数据库的 SQL 跟踪功能。以 Oracle 为例,可以在 AE 程序的 PeopleCode 里插入SQLExec("ALTER SESSION SET SQL_TRACE = TRUE"),然后在数据库的udump目录下查看跟踪文件。-- 在 PeopleCode Action 里开启 SQL 跟踪 SQLExec("ALTER SESSION SET SQL_TRACE = TRUE"); -- 程序执行结束后关闭跟踪 SQLExec("ALTER SESSION SET SQL_TRACE = FALSE");逻辑说明:SQL 跟踪会记录当前会话执行的所有 SQL 语句,包括执行次数和执行时间。通过分析跟踪文件,可以找出哪些 SQL 被频繁执行,从而定位性能瓶颈。参数说明:SQL_TRACE是 Oracle 的参数,其他数据库有类似的机制。开启跟踪会增加数据库的 I/O 负担,只建议在测试环境使用。跟踪文件的位置由数据库的user_dump_dest参数决定。5.4 一个我踩过的坑:临时表实例数设少了有一次我负责一个批量计算程序,State Record 用了临时表,实例数设了 3。测试环境没问题,但生产环境晚上跑批时,Process Scheduler 同时触发了 5 个实例,结果后两个实例一直在排队,整个跑批窗口被拉长了一倍。后来把实例数改成 8,问题解决。从那以后,我每次给 AE 程序配临时表,都会先确认 Process Scheduler 的最大并发数,然后按「最大并发数 × 1.5」来设实例数。另外,临时表的「记录类型」一定要选「临时表」,不要选「非临时表」,否则程序结束后数据不会自动清理,时间长了表会越来越大。希望这份文档能帮你在 PeopleSoft 人力系统的 AE 开发里少走点弯路。本文还有配套的精品资源,点击获取
简介:这份资源是PeopleSoft Application Engine的中文版官方文档,面向PeopleSoft开发人员、人力系统实施顾问及需要维护批量业务流程的技术人员。Application Engine作为PeopleSoft后台工作流的核心组件,承担数据更新、报表生成、接口同步等批量处理任务,文档通过深度翻译帮助中文用户理解其编程模型与运行机制。压缩包内仅含1个PDF文件,大小约2.25MB,内容源自Enterprise PeopleTools 8.50 PeopleBook,涵盖应用引擎概述、实施方法、程序元素(栏目、阶梯、行动)、Meta-SQL、并发执行、错误恢复、日志记录与性能优化等章节,并附有Oracle许可限制、保修声明及危险应用通知等法律条款。目前已有345人学习。读者可借助该文档掌握Application Engine程序的创建与配置流程,理解其与PeopleCode、Job、Process Scheduler的协同方式,并获取批量数据处理与定时任务设计的排错思路,适合作为日常开发与系统维护的案头参考。1. 从一份 2009 年的 PeopleBook 说起:AE 中文文档到底能解决什么如果你正在维护一套 PeopleSoft 人力系统,大概率遇到过这种场景:Process Scheduler 里某个 AE 程序跑了一半卡住,日志只给一行含糊的 SQL 错误,翻官方英文文档又全是术语堆叠,查一个%AeProgram的用法要来回跳三四个页面。这份《PeopleSoft Application Engine 中文文档》对应的就是 Enterprise PeopleTools 8.50 的 PeopleBook,SKU 为 pt850pbr0,内容覆盖从「开始使用应用引擎」到 Meta-SQL 参考的完整章节。它不是教程,也不是视频课,而是一份把官方英文手册逐章翻译过来的参考文档,适合已经上手 PeopleSoft、需要快速定位 AE 程序元素定义和 Meta-SQL 语法的开发者。换句话说,它解决的不是「AE 是什么」,而是「这个参数到底填什么、这个动作类型什么时候用」。2. 拆开 AE 程序结构:Section、Step、Action 三层到底怎么落2.1 程序元素的层级关系与定义视图Application Engine 程序的骨架是三层结构:Section(章节)→ Step(阶梯)→ Action(行动)。文档第二章把这个层级讲得很清楚,但真正上手时容易混淆的是「定义视图」和「程序流视图」的区别。定义视图是树状结构,适合批量调整属性;程序流视图是流程图式展示,适合看执行顺序。我一般习惯先在定义视图里把 Section 建好,再切到程序流视图检查 Step 的排列是否符合预期。每个 Section 可以设置自己的属性,比如是否启用、是否并行执行。Step 是执行的最小调度单位,一个 Step 里可以放多个 Action,Action 按顺序执行。这里有个容易翻车的地方:Step 的属性里有一个「On Error」选项,决定出错后是继续下一步还是中止整个程序。默认值不一定符合你的业务预期,尤其是涉及批量更新时,选错了会导致部分数据已提交、部分回滚。文档第三章详细列出了 Action 的类型:SQL、Do、PeopleCode、Call Section、Log Message、XSLT。每种 Action 有自己的属性面板,SQL Action 需要指定 SQL 类型(Select、Update、Insert 等),Do Action 需要指定是 Select、Fetch、When 还是其他。这些在文档里都有表格对照,但实际配置时最容易搞混的是 SQL Action 和 Do Action 的配合使用。2.2 用 State Record 传递状态:临时表与国家记录的选型State Record(状态记录)是 AE 程序里跨 Section、跨 Step 传递数据的核心机制。文档里叫「国家记录」,这个翻译有点生硬,但意思就是程序运行期间保存中间状态的记录。它本质上是一个 PeopleSoft 记录定义,可以基于物理表也可以基于临时表。选型时有个判断标准:如果程序是并发运行的,State Record 必须用临时表,否则多个实例会互相覆盖数据。文档在「为国家记录选择记录类型」一节里提到了这一点,但没有展开讲并发场景。我一般会这样处理:先确认这个 AE 程序会不会被多个 Process Scheduler 实例同时触发,如果是,State Record 对应的记录必须勾选「临时表」属性,并且要在 AE 程序属性里指定临时表实例数。设置 State Record 的步骤不复杂,但有几个参数容易漏:-- 在 AE 程序属性中指定 State Record -- 常见做法是在 PeopleTools 的 Application Engine 定义里 -- 找到「State Record」选项卡,填入记录名 -- 如果是临时表,还需要在「Temp Table」选项卡里 -- 指定实例数(通常设为 3 到 5,视并发量而定)逻辑说明:State Record 的名字必须是一个已存在的记录定义,不能临时创建。临时表实例数的含义是:每个并发实例分配一个独立的临时表副本,实例数决定了最大并发数。设得太少,高并发时会排队;设得太多,数据库里会多出一堆临时表,占用表空间。参数说明:实例数一般按「峰值并发数 × 1.5」估算。如果程序只在夜间跑一次,实例数设为 1 就够。另外,临时表的「记录类型」要选对,PeopleSoft 支持「临时表」和「非临时表」两种,前者在程序结束后自动清理数据,后者需要手动清理。2.3 批量插入与集合处理:为什么逐行处理是性能杀手文档第四章「制定高效的方案」里,最值得反复读的是「使用集合处理」和「避免逐行处理」这两节。AE 程序最常见的性能问题就是:用 PeopleCode 循环逐行读取数据,再逐行更新。这种写法在数据量小的时候看不出问题,一旦上万行就会慢得离谱。集合处理的核心思路是用 SQL 的Set操作代替逐行Fetch。具体做法是:在 SQL Action 里写一条UPDATE或INSERT ... SELECT语句,一次性处理整批数据,而不是在 PeopleCode 里循环。文档里给了一个例子,大意是把一个 Section 的 SQL 类型设为Update,然后在 SQL 编辑器里写批量更新语句。我一般会这样改造一个逐行处理的程序:-- 改造前:逐行处理(伪代码) -- 在 PeopleCode Action 里循环 Fetch 每一行 -- 然后逐行执行 UPDATE -- 改造后:集合处理 -- 在 SQL Action 里直接写: UPDATE PS_EMPLOYEE_TBL A SET A.STATUS = 'A' WHERE A.EMPLID IN ( SELECT B.EMPLID FROM PS_JOB B WHERE B.EFFDT = (SELECT MAX(C.EFFDT) FROM PS_JOB C WHERE C.EMPLID = B.EMPLID) AND B.ACTION = 'HIR' )逻辑说明:这条 SQL 一次性把所有符合条件的雇员状态更新为A,不需要在 PeopleCode 里循环。AE 的 SQL Action 会把整条语句交给数据库执行,数据库的批量处理能力远强于逐行 Fetch。参数说明:EFFDT的子查询是为了取最新生效日期,这是 PeopleSoft 人力系统里常见的「取最新记录」模式。注意IN子查询的性能,如果PS_JOB数据量很大,建议改成EXISTS或JOIN。另外,批量更新前一定要在测试环境验证 SQL 的WHERE条件,避免误更新。文档还提到了「使用批量插入」的技巧:如果目标表是空表或可以追加,用INSERT ... SELECT比逐行插入快一个数量级。但要注意,批量插入不会触发 PeopleCode 的SaveEdit和SavePreChange事件,如果业务逻辑依赖这些事件,就不能用批量插入。3. Meta-SQL 与 PeopleCode 的配合:什么时候用哪个3.1 Meta-SQL 的常用占位符与展开规则Meta-SQL 是 AE 程序里特有的 SQL 扩展,用%开头的占位符表示。文档第五章列出了完整的 Meta-SQL 参考,从%Abs到%AeStep都有。实际开发中最常用的几个是:Meta-SQL用途常见场景%AeProgram展开为当前 AE 程序名日志记录、错误信息%AeSection展开为当前 Section 名日志记录%AeStep展开为当前 Step 名日志记录%DateIn日期格式转换跨数据库日期处理%DateOut日期格式转换跨数据库日期处理%Table展开为记录对应的物理表名动态 SQL%SelectAll展开为记录的所有字段动态查询%Table和%SelectAll在写动态 SQL 时特别有用。比如你要写一个通用的查询,不想硬编码表名,就可以用%Table(record_name)。但要注意,Meta-SQL 是在 AE 程序编译时展开的,不是运行时,所以不能用在动态拼接的 SQL 字符串里。%DateIn和%DateOut是跨数据库兼容的关键。PeopleSoft 支持多种数据库,不同数据库的日期格式不一样,直接用字符串拼日期会翻车。我一般会在所有涉及日期的 SQL 里都用%DateIn包一层:-- 不推荐:硬编码日期格式 SELECT * FROM PS_EMPLOYEE_TBL WHERE HIRE_DT > '2024-01-01' -- 推荐:用 Meta-SQL 转换 SELECT * FROM PS_EMPLOYEE_TBL WHERE HIRE_DT > %DateIn('2024-01-01')逻辑说明:%DateIn会把字符串按当前数据库的日期格式转换成日期类型,避免因数据库差异导致的格式错误。%DateOut则相反,把日期类型转成字符串。参数说明:%DateIn的参数是一个字符串,格式必须是YYYY-MM-DD。如果传入的格式不对,AE 程序会在编译时报错。另外,%DateIn只能用在 SQL Action 里,不能用在 PeopleCode 里。3.2 PeopleCode 在 AE 中的调用时机与限制PeopleCode 在 AE 程序里是通过 PeopleCode Action 调用的。文档第五章「在应用引擎程序中使用PeopleCode」一节里,最关键的一句话是:PeopleCode Action 的执行上下文和在线页面不一样,很多在线可用的函数在 AE 里不可用。具体来说,AE 里的 PeopleCode 不能直接访问组件缓冲区(Component Buffer),因为 AE 没有组件上下文。如果你在 PeopleCode 里写了GetRowset或GetRecord,运行时会报错。正确的做法是用SQL对象或Record对象直接操作数据库。另一个限制是CommitWork函数。文档里专门有一节讲「使用CommitWork函数」,大意是 AE 程序默认在每个 Step 结束后自动提交,但如果你的程序需要手动控制提交点,可以在 PeopleCode 里调用CommitWork()。不过要注意,频繁提交会影响性能,而且一旦提交,回滚就回不去了。我一般会这样处理提交策略:如果程序是批量更新,且更新逻辑可以分批,就在每个 Section 结束后提交一次;如果更新逻辑必须全部成功或全部失败,就关掉自动提交,在程序最后手动提交。关掉自动提交的方法是在 AE 程序属性里把「Commit」选项设为「After Step」或「After Section」,具体选哪个看业务需求。3.3 同步在线调用 AE 程序的注意事项文档第五章提到了「对应用引擎程序进行同步在线调用」,这是一个容易被忽略但很有用的功能。默认情况下,AE 程序是通过 Process Scheduler 异步执行的,但有些场景需要同步执行,比如用户点击按钮后立即返回结果。同步调用的方法是在 PeopleCode 里用CallAppEngine函数:/* 同步调用 AE 程序 */ Local string &result; &result = CallAppEngine("MY_AE_PROGRAM", &stateRecord); /* 检查返回状态 */ If &result = "Success" Then /* 处理成功逻辑 */ Else /* 处理失败逻辑 */ End-If;逻辑说明:CallAppEngine会同步执行指定的 AE 程序,并返回执行结果。&stateRecord是一个 State Record 的引用,用于传递参数和接收返回值。参数说明:第一个参数是 AE 程序名,必须是已定义的程序。第二个参数是 State Record,类型必须是AppEngine支持的记录类型。注意,同步调用会阻塞当前线程,如果 AE 程序执行时间较长,用户界面会卡住,所以只适合短时间运行的逻辑。4. 避坑与排查:AE 程序最常见的五类翻车现场4.1 现象:程序跑完了但数据没更新原因:最常见的原因是 SQL Action 的Commit设置不对。AE 程序默认在每个 Step 结束后自动提交,但如果 Step 的属性里把Commit设成了Never,或者程序属性里关掉了自动提交,数据就不会落库。解决:检查 AE 程序属性的「Commit」选项,确认是After Step还是After Section。如果是手动提交模式,确认 PeopleCode 里有没有调用CommitWork()。另外,检查 SQL Action 的ReUse属性,如果设成了ReUse,Statement 会被缓存,可能导致后续执行时用了旧的绑定变量。4.2 现象:State Record 数据被覆盖原因:多个并发实例共用了同一个 State Record,且没有启用临时表。AE 程序在 Process Scheduler 里可以并发触发,如果 State Record 基于物理表,实例 A 写入的数据会被实例 B 覆盖。解决:把 State Record 对应的记录定义改成临时表,并在 AE 程序属性里设置足够的临时表实例数。临时表的实例数决定了最大并发数,设少了会排队,设多了会占用表空间。我一般按「峰值并发数 + 2」来设。4.3 现象:Meta-SQL 展开后 SQL 语法错误原因:Meta-SQL 占位符用在了不支持的位置。比如%Table只能用在FROM子句里,不能用在SELECT列表里。或者%DateIn的参数格式不对,导致展开后的 SQL 里出现了非法日期字符串。解决:在 AE 程序的「SQL 预览」功能里查看展开后的 SQL。PeopleTools 提供了一个 SQL 预览窗口,可以看到 Meta-SQL 展开后的实际语句。如果预览报错,说明占位符用法有问题。另外,注意%Table的参数必须是记录名,不是表名。4.4 现象:PeopleCode Action 报「找不到记录」原因:AE 里的 PeopleCode 没有组件上下文,不能用GetRecord或GetRowset直接访问页面上的记录。如果代码里写了这类函数,运行时会报「Record not found」或「Rowset not found」。解决:改用CreateRecord或SQL对象直接操作数据库。比如要读取一条记录,可以用SQL对象执行SELECT,然后把结果赋给变量。如果必须用记录对象,用CreateRecord(record_name)创建一个独立的记录实例,而不是从组件缓冲区获取。4.5 现象:程序执行时间过长,Process Scheduler 超时原因:逐行处理导致性能瓶颈,或者 SQL 没有走索引。AE 程序的默认超时时间由 Process Scheduler 的配置决定,如果程序执行时间超过阈值,会被强制终止。解决:把逐行处理改成集合处理,用UPDATE ... SELECT或INSERT ... SELECT代替循环。检查 SQL 的执行计划,确认WHERE条件里的字段有索引。如果程序确实需要长时间运行,可以在 Process Scheduler 里调整超时时间,但更好的做法是优化 SQL。另外,AE 程序的「Step」属性里有一个「On Error」选项,如果设成了Abort,一旦出错整个程序会立即终止,不会继续执行后续 Step。5. 进阶技巧:用日志和调试工具定位 AE 程序问题5.1 开启 AE 程序的详细日志AE 程序的日志默认只记录 Section 和 Step 的起止时间,不记录 SQL 语句和绑定变量。要排查问题,需要开启详细日志。方法是在 Process Scheduler 的「Process Definition」里,把 AE 程序的「Log Level」设为Debug或Trace。# 在 Process Scheduler 的 Process Definition 里 # 找到 AE 程序对应的 Process # 把 Log Level 从默认的 "Info" 改成 "Debug" # 然后重新提交程序 # 日志文件会生成在 Process Scheduler 的日志目录下 # 文件名通常是 AE_MYPROGRAM_<ProcessInstance>.log逻辑说明:Debug级别会记录每个 Action 的执行详情,包括 SQL 语句和绑定变量。Trace级别更详细,会记录 PeopleCode 的每一行执行。日志文件的位置由 Process Scheduler 的配置决定,一般在$PS_HOME/appserv/prcs/<domain>/logs目录下。参数说明:日志级别越高,生成的日志文件越大,对性能的影响也越明显。建议只在排查问题时开启Debug,问题解决后改回Info。另外,日志文件会占用磁盘空间,定期清理是必要的。5.2 用 AE 程序的「测试模式」单步执行PeopleTools 提供了一个「测试模式」,可以在 Application Designer 里单步执行 AE 程序。这个功能在文档里没有详细讲,但实际排查问题时非常有用。开启方法是在 Application Designer 里打开 AE 程序,点击「Test」按钮,然后选择要执行的 Section 和 Step。测试模式下,可以逐 Step 执行,查看每个 Step 的输入输出。如果某个 Step 的 SQL 有问题,测试模式会直接报错,并显示展开后的 SQL 语句。我一般会在修改 AE 程序后,先用测试模式跑一遍关键 Section,确认没有语法错误再提交到 Process Scheduler。5.3 用 SQL 跟踪定位性能瓶颈如果 AE 程序的性能问题不在 SQL 本身,而在 PeopleCode 的循环逻辑,可以用数据库的 SQL 跟踪功能。以 Oracle 为例,可以在 AE 程序的 PeopleCode 里插入SQLExec("ALTER SESSION SET SQL_TRACE = TRUE"),然后在数据库的udump目录下查看跟踪文件。-- 在 PeopleCode Action 里开启 SQL 跟踪 SQLExec("ALTER SESSION SET SQL_TRACE = TRUE"); -- 程序执行结束后关闭跟踪 SQLExec("ALTER SESSION SET SQL_TRACE = FALSE");逻辑说明:SQL 跟踪会记录当前会话执行的所有 SQL 语句,包括执行次数和执行时间。通过分析跟踪文件,可以找出哪些 SQL 被频繁执行,从而定位性能瓶颈。参数说明:SQL_TRACE是 Oracle 的参数,其他数据库有类似的机制。开启跟踪会增加数据库的 I/O 负担,只建议在测试环境使用。跟踪文件的位置由数据库的user_dump_dest参数决定。5.4 一个我踩过的坑:临时表实例数设少了有一次我负责一个批量计算程序,State Record 用了临时表,实例数设了 3。测试环境没问题,但生产环境晚上跑批时,Process Scheduler 同时触发了 5 个实例,结果后两个实例一直在排队,整个跑批窗口被拉长了一倍。后来把实例数改成 8,问题解决。从那以后,我每次给 AE 程序配临时表,都会先确认 Process Scheduler 的最大并发数,然后按「最大并发数 × 1.5」来设实例数。另外,临时表的「记录类型」一定要选「临时表」,不要选「非临时表」,否则程序结束后数据不会自动清理,时间长了表会越来越大。希望这份文档能帮你在 PeopleSoft 人力系统的 AE 开发里少走点弯路。本文还有配套的精品资源,点击获取