简介:面向使用 Informatica 进行数据集成与 ETL 开发的工程师,提供调用存储过程的图文流程说明,帮助解决数据加载前需要执行预处理逻辑时的配置难题。文档按实际界面操作顺序展开,覆盖新建 Mapping、右键目标表进入编辑、切换到属性选项卡、在 pre SQL 栏写入调用脚本,以及通过变量替换入参等关键节点;同时对存储过程的作用、调用优点(提升集成速度、数据安全性与可靠性)及数据迁移、数据同步、报表生成等典型应用场景做了补充说明。各关键步骤均配有界面截图与文字注解,降低新手摸索成本,也可作为中高级开发人员的快速查阅手册。资源为压缩包,包含 1 个 docx 文档,体积约 180KB,内容集中、无冗余,打开即可按步骤对照操作,适合在项目开发或日常运维中随时查阅。已有 976 人浏览学习,遇到同类需求时可作为直接参照。
1. Informatica 调用存储过程:先别急着找专用组件,pre SQL 才是主力
接触 Informatica 的开发者,第一次接到“在同步数据前先调用存储过程”这种需求,大概率会去组件面板里翻有没有专门的 Stored Procedure 组件。实际上在常规的 Mapping 开发里,调用存储过程最直接的入口,藏在目标表的属性选项卡里,通过 Pre SQL 字段就能把脚本灌进去,配合变量替换把入参传到位。这个功能在数据迁移、报表预处理、数据同步场景里都特别常用,适合所有用 PowerCenter 或同类 Informatica 产品做 ETL 开发的人。这篇文章就围绕 Mapping 中调用存储过程的完整链路,把原理、图文步骤、变量绑定和几个高频坑一次讲透。
2. 理解 pre SQL 机制:调用时机、会话连接与 SQL 前置条件的取舍
2.1 pre SQL 与存储过程在 ETL 中的分工
Informatica 的 Mapping 由 Source、Transform、Target 三类对象组成,加载动作由 Session 驱动。Session 在执行时有一套内部顺序:先是 Source 端抽取准备,然后是 Target 端预处理,再进入数据流写入,最后是 Target 端后处理。Pre SQL 就是挂在 Target 预处理阶段执行的 SQL 脚本,在数据流还没有向目标表写任何记录之前运行。
从设计上说,pre SQL 承担两类职责:一类是环境准备,例如建临时表、清空目标分区、修改会话参数;另一类是业务逻辑前置,例如调用存储过程初始化汇总表、更新批次状态、生成序列号。调用存储过程属于后者的典型用法。很多人以为存储过程调用必须依赖专门的组件,其实在数据加载场景下,直接用 pre SQL 写调用语句的收益非常明显,配置量小、结构清晰、出问题了好排查。
存储过程本身的优势也在这里得到放大。它是编译过的 SQL 集合,批量处理能力强,还天然带有权限管控能力。通过 pre SQL 调用存储过程,相当于把“压舱”的逻辑放在数据库内部执行,而不是把大量行数据拉到 Informatica 引擎里做变换,这对网络负载和内存占用都是友好的。
2.2 会话连接属性:为什么脚本能跑、参数传不过去
Mapping 里的目标表配置了关系型连接,这个连接决定了 pre SQL 在哪一个数据库会话里执行。很多跑不通的情况,问题不在脚本本身,而在连接的属性设置,尤其是事务控制方式。
在我的开发习惯里,打开 Session 的任务属性,切到 Properties 选项卡,会重点检查两个地方。一个是 Connection 区域里目标表连接是否选对,另一个是 Transaction 属性里 change 模式的设置。pre SQL 虽然写在 Target 的属性里,但实际执行在 Session 建立的数据库会话上。如果你在映射里混用了多个源连接,而目标连接本身又指向了错误的数据库实例,那 pre SQL 里写的存储过程名即使一半分毫不差,也会因为“找不到对象”或者“无效用户名”被弹回来。
另外要注意的是,在 pre SQL 里调用存储过程跟在数据库客户端里直接执行不同,Informatica 会复用会话的事务边界。存储过程里如果自己写了 commit,有可能会跟整体会话事务冲突,造成后续数据加载的状态不可预期,这一点在后面的避坑章节里会详细展开。
2.3 手动创建存储过程:贴入这段 SQL 先备好依赖
在配置 Mapping 之前,先确认存储过程已经在目标库里存在,这是最基础的一步。下面是一段典型的 Oracle 存储过程,模拟根据日期参数更新统计表。
CREATE OR REPLACE PROCEDURE PROC_INIT_DAILY_SUMMARY( P_BIZ_DATE IN VARCHAR2, P_TOTAL_OUT IN OUT NUMBER ) AS V_COUNT NUMBER; BEGIN DELETE FROM DAILY_SUMMARY WHERE BIZ_DATE = P_BIZ_DATE; INSERT INTO DAILY_SUMMARY(BIZ_DATE, RECORD_COUNT) SELECT P_BIZ_DATE, COUNT(*) FROM MAIN_TRANSACTION WHERE TRUNC(CREATE_TIME) = TO_DATE(P_BIZ_DATE, 'YYYY-MM-DD'); SELECT COUNT(*) INTO V_COUNT FROM DAILY_SUMMARY WHERE BIZ_DATE = P_BIZ_DATE; P_TOTAL_OUT := V_COUNT; EXCEPTION WHEN OTHERS THEN P_TOTAL_OUT := -1; END PROC_INIT_DAILY_SUMMARY;逻辑说明:这段脚本先按业务日期清理当日汇总数据,再从主交易表聚合写入汇总表,最后把记录数通过 OUT 参数传回去,方便 Informatica 侧做后续判断。
参数说明:P_BIZ_DATE 是入参,表示业务日期,在 Informatica 中可以用变量替换;P_TOTAL_OUT 是出参,适合验证调用是否真实生效。如果你的平台是 SQL Server,换一种写法:
CREATE PROCEDURE PROC_INIT_DAILY_SUMMARY @P_BIZ_DATE VARCHAR(10), @P_TOTAL_OUT INT OUTPUT AS BEGIN DELETE FROM DAILY_SUMMARY WHERE BIZ_DATE = @P_BIZ_DATE; INSERT INTO DAILY_SUMMARY(BIZ_DATE, RECORD_COUNT) SELECT @P_BIZ_DATE, COUNT(*) FROM MAIN_TRANSACTION WHERE CONVERT(CHAR(10), CREATE_TIME, 23) = @P_BIZ_DATE; SELECT @P_TOTAL_OUT = COUNT(*) FROM DAILY_SUMMARY WHERE BIZ_DATE = @P_BIZ_DATE; END;存储过程结构保持简单,别在过程里堆太多业务分支,方便后续在 Informatica 里做黑盒调用。
3. 图文实操:从新建 Mapping 到 pre SQL 写入完成调用
3.1 新建 Mapping 并配置目标表
打开 Informatica 客户端,在 Designer 里创建新的 Mapping。大多数场景下,源表可以选择一张占位表,目标表选择业务要落数据的表。这里的重点不是数据流多复杂,而是目标表的属性配置。
在 Mapping 区域,右键目标表,选择 Edit,然后切到 Properties 选项卡。这一步很多人容易迷路,因为左侧是属性列表,右侧是属性值,Pre SQL 属性默认是空的,要手动展开找到。以 PowerCenter 9.x 和 10.x 为例,属性列表里会明确出现 “Pre SQL” 和 “Post SQL” 两个字段,分别在数据加载前和加载后执行。
在这个位置写入调用语句,保存之后任务执行时就会按顺序触发。注意这里写入的是数据库方言,不是 Informatica 自己的语法,所以 Oracle 就写 PL/SQL 风格,SQL Server 就写 T-SQL 风格,不同平台不能互换。
3.2 在属性选项卡写入调用脚本
右键目标表选择 Edit 后,把界面切到属性选项卡,在 Pre SQL 一栏写入调用存储过程的语句。这一步的关键是搞清楚你的连接类型对应的调用语法。下面是几种常见写法。
Oracle 数据库调用存储过程时,推荐用 CALL 或 BEGIN END 包裹:
BEGIN PROC_INIT_DAILY_SUMMARY('2025-03-17', :TOTAL_OUT_PARAM); END;逻辑说明:BEGIN END 是 PL/SQL 匿名块的标准写法,适合包含多条语句的场景;CALL 更适合单条存储过程调用。
参数说明::TOTAL_OUT_PARAM 是绑定变量占位符,这个变量如果暂时不想绑定,可以先写死一个普通变量值,后面再改造成 Informatica 参数。
SQL Server 平台则写成这样:
EXEC PROC_INIT_DAILY_SUMMARY @P_BIZ_DATE = '2025-03-17', @P_TOTAL_OUT = ? OUTPUT;逻辑说明:EXEC 是 T-SQL 调用存储过程的命令,OUTPUT 关键字声明了出参方向。
参数说明:这里的问号占位符同样用于 Informatica 参数绑定。如果只写常量,这部分就跟数据库客户端执行没区别。
如果你的 pre SQL 要覆盖更复杂的场景,比如先清空临时表再调用,也写在同一栏里,用分号或斜杠分隔,Informatica 会整体提交给数据库执行。
3.3 保存与跑通的第一个最小示例
写入脚本后,保存 Mapping,然后回到 Workflow Manager 创建一个 Session,复用这个 Mapping 指向的连接即可。这里我建议先做一个最小示例打通链路,不要一开始就上复杂的多表映射。最小示例可以直接建一张空表作为目标表,源端选择任意小表,目的是验证 pre SQL 能不能正常跑,存储过程有没有被调用。
创建一个可控的验证专用过程,不需要业务表参与,就能判断链路是否畅通:
CREATE OR REPLACE PROCEDURE PROC_TEST_INVOKE AS BEGIN INSERT INTO INVOKE_LOG(PROC_NAME, INVOKE_TIME) VALUES('PROC_TEST_INVOKE', SYSDATE); COMMIT; END PROC_TEST_INVOKE;然后在 pre SQL 里写:
BEGIN PROC_TEST_INVOKE; END;跑完 Session,去数据库查看 INVOKE_LOG 表里是否新增了记录。如果记录有了,说明链路通;如果没有,优先打包检查 Session 日志里的 Database Error 信息。这样的小实验能把问题暴露在可控范围内,而不是等生产环境里几百张表跑完才发现存储过程压根没被触发。
从这一步开始,后面的变量绑定、参数文件、多环境切换,都可以在这个最小工程上逐步叠加,可以少走不少弯路。
4. 变量与参数绑定:把硬编码改造成可复用的会话参数
4.1 变量来源:参数文件、Session 配置与 Mapping 变量
pre SQL 里如果全是硬编码日期、硬编码编号,换一次业务周期就要改一次 Mapping,这在开发环境还可以接受,到了生产环境简直是一场灾难。Informatica 的变量体系正好用来解决这个问题。
变量来源主要有三个层面。第一个是 Workflow 级参数文件,格式是[WorkflowName]下定义键值对,适用于跨环境切换场景;第二个是 Session 参数,比如$sessStartTime,可以在 Session 属性里绑定;第三个是 Mapping 变量,定义在 Mapping 属性里,适合数据流内部传递状态。对于 pre SQL 调用存储过程来说,最常配合使用的是参数文件和 Session 参数。
它们的赋值规律很像作用域规则,内层覆盖外层,特定前缀决定了变量的适用范围。简单理解就是:只会用$$、$和?这三种前缀。$$是全局参数,$是 Session 或 Mapping 参数,?是绑定参数。三种前缀对应不同的作用域,不能随意混用。
4.2 在 pre SQL 中绑定参数
存储过程的入参需要在 pre SQL 里进行变量替换。举例,Oracle 连接下的 pre SQL 可以写成这样:
BEGIN PROC_INIT_DAILY_SUMMARY($$BIZ_DATE, :OUT_VAL); END;这里$$BIZ_DATE会被参数文件中定义的值替换。参数文件格式大致如下:
[WF_INIT_DAILY] BIZ_DATE=2025-03-17 DB_USER=ETL_USER注意键名不带$$,参数文件名与 Workflow 同名,放在指定目录下。Session 运行时,Informatica 会自动读取并替换。
SQL Server 平台写法类似:
EXEC PROC_INIT_DAILY_SUMMARY @P_BIZ_DATE = $$BIZ_DATE, @P_TOTAL_OUT = ? OUTPUT;参数替换的机制相对直观,但有一个细节要特别小心:参数替换是文本替换。如果你把$$BIZ_DATE定义成2025-03-17,最终拼接出来就是不带引号的字符串,在 Oracle 的 PL/SQL 块里会报错。解决方法是参数文件里直接把值写成'2025-03-17',把单引号包含进去。这个细节最容易让人翻车,而且错误提示常常不是“参数未定义”,而是 ORA-00904 之类的无效标识符错误,容易绕圈子。
4.3 参数传入失败的常见信号
参数绑定失败通常不是 Informatica 直接拦截,而是在数据库一侧报出各种“看不懂”的错误。最常见的是 ORA-00904 无效标识符,看到这个先不要怀疑字段名,优先怀疑字符串变量缺引号。再一个是绑定变量数量不匹配,比如存储过程有两个入参,pre SQL 里只写了一个,数据库会直接报参数个数错误。
还有一个隐性坑是绑定参数方向不匹配。在 Oracle 里如果存储过程有出参,而你在 pre SQL 里没有为出参绑定对应的占位符,调用会直接失败;反过来说你绑了出参但过程定义没有 OUT 参数,同样是参数个数错误。排查的顺序我一般是这样:先在数据库客户端里把存储过程原型跑通,确认语法没问题,再回到 Informatica 侧逐层替换变量。用数据库客户端打完底,再进工具,排错范围能缩小很多。
另外,写参数文件时注意编码,尤其是日期字段带中文注释或特殊字符时,别用带 BOM 的 UTF-8 格式保存,不然 Session 读取到第一行就会报错。
5. 避坑指南:pre SQL 调存储过程的 4 个血泪坑
5.1 抽数时存储过程被反复执行
现象:Mapping 跑完,检查日志发现存储过程被执行了很多次,业务表数据重复初始化。
原因:pre SQL 的执行时机和分区数量相关。当目标表设置了多个分区写入,或者映射里存在多个 Target 实例指向同一张表结构时,Informatica 会为每个分区或每个目标实例执行一次目标表的预处理 SQL,存储过程自然被多次调用。
解决:先在 Session 属性里确认目标表写模式,尽量让 pre SQL 的执行次数与预期匹配。更稳的做法是在存储过程内部做幂等保护,比如先删除当日数据再插入,这样即使执行两次,最终结果仍只有一份记录。如果存储过程本身不幂等,那就要调整映射结构,把多个目标合并成一个,或者把存储过程调用挪到 Session 级预处理中,只在任务开始执行一次。
5.2 Commit 与事务边界不受控
现象:pre SQL 调用的存储过程执行成功,但后续数据加载出现无法解释的数据丢失,或者回滚行为异常。
原因:Informatica 的 Session 有自己的事务控制机制,pre SQL 默认会在该事务上下文中执行。存储过程内部如果包含 COMMIT 语句,会提前提交当前事务的部分操作,导致后续加载出现问题。
解决:存储过程设计阶段约定内部不写 COMMIT;如果存储过程来自第三方或历史库,无法改动,就在调用前确认是否可以先独立连接执行。另一个可行方向是把调用拆到 Workflow 层面,在一个独立 Session 里先执行存储过程,完成后再启动数据加载 Session,两个 Session 之间靠调度依赖控制先后关系,事务互不干扰。
5.3 目标表前缀名与连接映射错位
现象:pre SQL 的脚本单独在数据库工具里执行没有问题,放到 Session 里就报“表或视图不存在”。
原因:映射里的目标表定义可能与实际数据库对象不一致,尤其是通过导入方式生成的目标表定义保留了源库的前缀名或用户名前缀,而 Session 连接的用户没有对应权限或有同名不同库的干扰。
解决:查看目标表的属性,把 Owner Name 和 Table Name 与实际库对象对齐。如果数据库里存在多个 Schema 下的同名存储过程,还要在 pre SQL 里显式加上 Schema 前缀,例如BEGIN SCHEMA_OWNER.PROC_INIT_DAILY_SUMMARY(...); END;,避免解析到错误的对象。这个问题在维护混合环境的团队里碰到的频率很高,往往一次连接串库,后面全部脚本都会跟着错位。
5.4 参数格式在 Oracle 与 SQL Server 之间的差异
现象:同一套 Mapping,换了数据库连接后,pre SQL 报错且错误信息指向语法。
原因:不同数据库平台的字符串引用和调用语法不同。Oracle 的匿名块要求字符串字面量带单引号,SQL Server 的 EXEC 对字符串引号宽容一些,但对 OUTPUT 占位符有严格要求。
解决:养成按数据库方言写 pre SQL 的习惯。平台切换时不能只改存储过程内容,前置调用的写法也必须同步调整。这里给出 SQL Server 的规范写法示例:
DECLARE @OUT_VAL INT; EXEC PROC_INIT_DAILY_SUMMARY @P_BIZ_DATE = '2025-03-17', @P_TOTAL_OUT = @OUT_VAL OUTPUT; SELECT @OUT_VAL AS TOTAL_OUT;逻辑说明:先用 DECLARE 声明出参变量,EXEC 调用后可以用 SELECT 把出参值打印出来,方便在日志里查看。
参数说明:@OUT_VAL 是 T-SQL 局部变量,跟 Informatica 的参数替换没有直接关系,需要区分这两套变量体系。
5.5 存储过程执行异常但 Session 显示成功
现象:存储过程内部报错,但 Session 日志里显示 Task 成功,数据加载继续执行。
原因:pre SQL 中的调用语句没有配置为失败即中止。Informatica 默认某些数据库错误不会直接终止整个 Session,尤其是 PL/SQL 匿名块中内部异常被捕获后,外层接收到的可能是成功状态。
解决:在 Session 的任务属性里,把 On Error 相关的失败条件调整严格,同时依赖存储过程自身的异常传播,不要吞掉错误。更实用的方式是在存储过程里做日志记录,并在 pre SQL 调用后检查标志位。如果调用结果有值返回,可以通过后续检查节点来验证,让失败尽早暴露。
6. 进阶用法:参数文件驱动、结果验证与 post SQL 兜底
6.1 用参数文件做多环境切换
开发、测试、生产三套环境共用一份 Mapping 是企业里最常见的诉求。要做到这一点,核心是把环境相关的内容全部收敛到参数文件里。目标表连接可以配置成参数,存储过程名的 Schema 前缀也可以参数化,连同 pre SQL 里的日期入参一并收敛。部署到新环境时,只需要替换参数文件,Mapping 本身不需要再打开修改,从源头减少误操作几率。
6.2 跑完后查这些表验证调用真实生效
验证阶段要把 Session 日志和数据库侧日志配合起来看。先查调用存储过程的日志表,例如看 INVOKE_LOG 里是否有本次调用的时间戳;再看业务目标表的数据是否符合存储过程处理的预期。如果存储过程有出参,将出参写入到一张验证表,或者在 Session 日志中打印出来,这样可以辅助判断执行路径是否完整走完。Session 日志里找到 pre SQL 相关片段,确认没有 Warning 级别以上的错误信息,再对比业务表记录数,基本就能断定调用链路是否健康。
6.3 post SQL 兜底与幂等性检查
pre SQL 负责加载前初始化,post SQL 负责加载后收尾。常见用法是在 post SQL 里执行统计信息刷新或生成汇总标志。注意 post SQL 存在同样的多执行问题,所以脚本设计上同样要求可重入。每次新增存储过程调用任务,我都会在 Mapping 开发完成后强制走一遍三查:查参数文件是否有残留硬编码、查日志表调用记录是否唯一、查重复跑两遍之后业务数据是否幂等。这个习惯养成之后,存储过程调用相关的上线返工基本能降掉大半。
希望这片拆解能帮你在 Informatica 里把存储过程调用用得顺手。
本文还有配套的精品资源,点击获取