☰
Informatica调用存储过程:SPT与SQLT配置避坑指南
2026/10/14 17:56:35 网站建设 项目流程

简介:资源为Informatica调用存储过程的图文流程说明文档,面向使用Informatica进行数据集成与ETL开发的工程师,解决在Mapping中通过pre SQL调用存储过程、传递参数并完成运行的关键需求。包体为单一docx文件,共1份,压缩包约180KB,内容集中、便于查阅。文档从新建映射入手,依次展示了右键目标表编辑、属性选项卡中写入pre SQL脚本、变量替换入参等完整操作路径,同时配有步骤截图和文字说明,能帮助读者快速理解每个操作位置。文中还梳理了存储过程的基本概念,归纳了调用存储过程在提升集成速度、数据安全性与可靠性方面的优势,并结合数据迁移、数据同步、报表生成等典型场景说明适用场景。目前已有976人学习下载,特别适合初次接触Informatica调用存储过程、希望按图文步骤独立完成配置的数据开发人员。

1. 一眼看懂:Informatica里为什么非要调存储过程

有人觉得,Informatica 是 ETL 工具,数据清洗、转换、加载都能在映射里完成,何必再绕一圈去调数据库里的存储过程?但真实的数据仓库项目里,你会频繁遇到这类需求:每天凌晨同步订单数据之前,要先按业务日期把目标表的当天分区清掉;同步完成之后,要调用一个统计过程刷新汇总表;或者源系统给你留了一个视图,但视图背后必须执行一段复杂的 PL/SQL 才能算出来。这些逻辑已经沉淀在数据库里,不可能为了 ETL 重写一遍,也不应该在 Informatica 里用一堆转换器去模拟——直接调用存储过程,是成本最低、也最符合现有系统架构的做法。这篇笔记想讲的,就是这条路的完整走法:有哪些调用方式、每一步怎么配置、参数怎么接、以及最容易翻车的几个环节。

2. 调用方式怎么选:SPT、SQLT 与表达式直调的三条路线

2.1 三条路线的本质差别

Informatica PowerCenter 里可以调存储过程的途径,常见的有三种,很多新手会卡在“到底用哪个”。我先讲清楚它们的定位,再做对比。

第一种是 Stored Procedure Transformation(SPT),映射里专门为调用存储过程设计的一个转换器。它最大的特点是能参与映射的数据流:你可以把源表某个字段作为输入参数传给存储过程,存储过程跑完后,它的输出参数还能回到映射里继续参与下游计算。适合的场景是“调存储过程是这个映射必须经历的一步”,比如同步前清数、同步后做某个更新操作。

第二种是 SQL Transformation(SQLT),本质上是执行一段 SQL 语句,而调用存储过程只是这段 SQL 的一种形式。它更灵活,能写子查询、能返回结果集,适合“我需要存储过程处理后返回一张表,再拿这张表和源做关联”的场景。很多项目的通用做法是:用 SQLT 直接执行CALL xxx(...),并且把返回的结果集一行行往下游流。SQLT 和 SPT 最大的不同,在于 SPT 是“一次调用、一个返回”,而 SQLT 可以“一次调用、返回多行”。

第三种是表达式里直调,例如在 Expression Transformation 里写proc_return := MY_PROC(:in_param)。这种方式适合数据库方言支持函数式返回的存储过程,且返回的是标量值,并不常见,大多数项目只用前两种。

2.2 选型判断标准与对比表

我一般会按三个问题来判断:

存储过程要不要返回数据给映射?不要,用 SPT;要,且返回多行,用 SQLT;要,但只是单个值,两种都可以,看团队维护习惯。

存储过程是同步执行还是异步批量?SPT 的调用时机受映射数据流驱动,适合“这一行到了这个节点才执行”;SQLT 更适合“我不管数据流,我就要在某个点整体执行一次”。

你的数据库方言对存储过程支持到什么程度?Oracle 里 SPT 支持很好,但到了部分数据库,存储过程的出参和 Informatica 端口的类型映射会出现各种问题,此时 SQLT 用原生 SQL 方言包一层,往往更稳定。

项目里最常见的坑是:明明应该用 SQLT,却选了 SPT,结果存储过程返回的多行结果集被硬生生截断成一行;或者反过来,SPT 就能解决的问题,用 SQLT 写了一大段 SQL,出了错还不好排查。所以下面的选择表请直接抄作业。

判断维度Stored Procedure TransformationSQL Transformation
调用形态映射内的转换器,有独立的输入输出端口一段 SQL 语句,支持CALL、SELECT等
返回多行结果集不支持,只处理单次调用的出入参支持,结果集可直接作为下游数据源
调用时机随数据流逐行/逐批触发随数据流触发,也可配置为每行执行
事务回滚受会话事务管理影响同样受会话事务管理影响
常见使用场景清数、更新统计信息、按主键处理单条逻辑存储过程返回游标、执行复杂 PL/SQL 并取回结果
适用对象目标端是存储过程时也可以用它作为目标跑原生 SQL 脚本,适合团队里 SQL 功底强的人

一句话总结:SPT 是“过程调用器”,SQLT 是“SQL 执行器 + 结果集接收器”。下面两章分别把它们的配置流程走一遍。

3. 用 Stored Procedure Transformation 跑通最小样例:一张映射的完整配置

3.1 场景与前置准备

先给一个可以在测试环境直接复现的场景:源表ORDERS每天有增量数据要做增量加载到ORDERS_HIS,但在加载前,必须先执行数据库里的存储过程CLEAN_ORDERS_HIS(pi_date IN DATE),把目标表当天已有的老数据删掉,防止重复。这个存储过程可以用最简单的 PL/SQL 先造出来:

CREATE OR REPLACE PROCEDURE CLEAN_ORDERS_HIS(pi_date IN DATE) AS BEGIN DELETE FROM ORDERS_HIS WHERE biz_date = pi_date; COMMIT; END CLEAN_ORDERS_HIS;

这里用了COMMIT,后面避坑章节会专门聊它和 Informatica 事务交互的问题,先按“存储过程自己管事务”的方式跑通。

前置准备三步:确认 Informatica 的集成服务能连上目标数据库,也就是连接对象已经建好且测试通过;确认映射用到的源表、目标表都已导入仓库;确认运行映射的用户对存储过程有 EXECUTE 权限。这三步缺一个,后面全是白忙。

3.2 建 SPT 转换器的界面操作与关键属性

在 Mapping Designer 里新建一个 Transformation,类型选 Stored Procedure。命名建议带业务含义,比如SP_CLEAN_ORDERS,别叫SP_1,不然三个月后你自己都看不懂。

创建完之后,双击进入编辑界面,有几个关键属性必须填对:

属性名推荐配置说明
Call TextCALL CLEAN_ORDERS_HIS(:pi_date)调用语句,:pi_date对应转换器里的端口变量
连接信息选择目标库对应的连接对象存储过程在哪个库,就选哪个连接
Stored Procedure Type选Normal表示作为映射内普通转换器使用
输入端口手动建立一个pi_date,类型为 DateTime端口名要和 Call Text 里的变量名一致

Call Text 语法是这里比较容易错的地方。常见写法有两种:一种是CALL 过程名(?, ?),?按端口顺序匹配;另一种是CALL 过程名(:端口名),按端口名匹配。我强烈推荐第二种,因为映射里端口重命名后,第一种写法的顺序很容易对不上,排查起来非常痛苦。

设置完属性,还需要在端口列表里把输入输出端口补齐。pi_date是输入端口,如果存储过程有 OUT 参数或返回值,还要建立对应的输出端口,比如po_count,类型设为 Integer。Call Text 里怎么写,决定了 Informatica 如何绑定这些端口:

CALL CLEAN_ORDERS_HIS(:pi_date, :po_count)

这里po_count就会接收存储过程的出参。注意:如果存储过程没有 OUT 参数,但你想知道删了多少行,可以在数据库端改造一下,加一个po_count OUT INTEGER,然后在过程体内用SELECT COUNT(*) INTO po_count FROM ORDERS_HIS WHERE biz_date = pi_date之类的语句把行数带出来。

3.3 在映射里连接端口并配置会话

回到 Mapping Designer 画布,把 SPT 放在源表和目标表之间。常见连线方式是这样:

  • 源表ORDERS不需要连到 SPT,因为pi_date通常来自一个变量或参数文件;
  • 用一个 Expression 转换器或直接使用映射参数$$BIZ_DATE,把它连到 SPT 的输入端口pi_date;
  • SPT 的输出端口如果需要,可以连到目标表的一个占位列,也可以不连,取决于你的业务要不要用到返回值。

如果你的场景是“先清数再加载”,映射的逻辑是:先让 SPT 跑完,再跑源到目标的主数据流。控制方式有两种:一是把 SPT 放在数据流链路上,让它的输出端口连接到目标表,这样数据会先经过 SPT 再流向目标;二是把 SPT 和目标表断开,用会话里的“存储过程计划”来指定它在源提取前还是目标加载后执行。第二种方式更干净,强烈建议优先用会话计划,而不是在映射数据流里强行串联。

配置会话时,在 Sessions 标签页找到存储过程相关的计划设置,把执行时机设为“源前”(Source Pre-load),或者在映射内让它作为第一个转换器执行。另外还有一个容易忽略的地方:会话的“属性”里,有一个“Commit on Success”选项,它控制映射成功后是否提交事务。如果你在数据库端已经 COMMIT,这里建议保持默认就好。如果你在存储过程里没有 COMMIT,而 Commit on Success 又开了,那么 SPT 的执行结果可能被 Informatica 管理的事务边界延迟提交——这个问题留到避坑章节细说。

3.4 跑通后的验证命令

映射跑完,先别急着看目标表,直接去数据库查一下存储过程到底执行没执行。最直接的办法是查数据库的会话视图。以 Oracle 为例:

SELECT sql_id, sql_text, executions FROM v$sql WHERE sql_text LIKE '%CLEAN_ORDERS_HIS%' ORDER BY last_active_time DESC;

看到executions增加了,说明确实被调起来了。再查目标表行数:

SELECT biz_date, COUNT(*) FROM ORDERS_HIS GROUP BY biz_date;

如果当天数据被清掉了,说明流程正确。注意,v$sql里查不到不代表没执行,可能存在绑定变量导致sql_text不完全匹配,所以更稳妥的办法是在存储过程里临时加一句写日志表的语句,或者用数据库的审计功能。

4. 走 SQL Transformation 这条路:不建 SPT 也能调用

4.1 SQLT 的定位与适用边界

前文提到 SQLT 适合“存储过程返回结果集”的场景。实际工作中,我遇到过不少这样的情况:存储过程内部做了一系列复杂的计算,最后通过OPEN cur FOR SELECT ...返回一个游标,应用程序需要拿到这个游标的结果集,再和别的数据源做关联。如果用 SPT,游标根本接不住;但用 SQLT,直接在 SQL Query 里写一段SELECT * FROM TABLE(...)或者CALL ...,结果就能作为数据源流出来。

另外一个常见做法是:存储过程本身没有返回游标,只是执行一段 DML 或 DDL,SQLT 可以直接作为“执行一次”的工具。但这时候,SPT 通常是更优解,因为它出错了更容易定位到具体哪一次调用失败。

4.2 在 SQLT 里调用存储过程并取回结果集

创建一个 SQL Transformation,命名如SQLT_CLEAN_AND_RETURN,然后配置它的 SQL Query 属性。这里有个关键点:SQLT 的 SQL Query 有两种模式,一种是SELECT查询,专门用来返回数据;另一种是“非 SELECT”,比如CALL或INSERT。如果你要调用存储过程并取回游标,建议写 SELECT 形式的包装语句:

SELECT * FROM TABLE(MY_PKG.GET_ORDERS_BY_DATE(:pi_date))

如果存储过程返回的是SYS_REFCURSOR,就不能直接用TABLE函数,这时候需要先创建一个流水线函数包一层,这是数据库端的活。单纯想让 SQLT 执行一次CALL,就这样写:

CALL CLEAN_ORDERS_HIS(:pi_date)

注意:SQLT 里的CALL语句,除了参数端口绑定,不要在里面写分号。Informatica 会把它当作一条 SQL 发送给数据库,分号可能引发语法错误,这一点和你在 SQL*Plus 里的习惯不一样,值得特别记住。最后在端口设置里,把pi_date配成输入参数,把查询结果需要的字段配成输出端口。

4.3 SQLT 的输入输出端口配置与常见误区

SQLT 的端口配置比 SPT 稍微绕一点。它的输入端口必须在 SQL Query 里用:端口名引用,输出端口会自动出现在“输出端口”列表里。有几个常见误区:

第一,SQLT 默认认为 SQL 语句是查询,如果你写CALL而不是SELECT,某些版本会报“SQL 语句不是查询”的校验错误。这时候需要确认 SQLT 的属性设置了允许非查询 SQL。

第二,SQLT 每行执行还是整体执行,取决于你怎么连输入端口。如果你把上游数据流连到输入端口,它会每行执行一次;如果你把输入端口留空,只在 Session 参数里赋值,那可以理解为执行一次。很多人想“我就让它跑一次”,结果发现性能和资源开销不对劲,就是这里连线的锅。

第三,SQLT 结果的输出端口类型要和数据库字段类型对得上。VARCHAR2 和 String 在 Informatica 里的隐式转换一般不报错,但如果存储过程返回的字段是 NUMBER(18, 4),映射端口设成 Integer,小数部分直接截断,数据错得悄无声息。

配置项建议值说明
SQL QueryCALL CLEAN_ORDERS_HIS(:pi_date)不写分号,参数端口用冒号绑定
入参端口pi_date,类型 DateTime与查询里引用同名
出参端口按需建立没有特殊需求时可不建出参
连接对象目标库连接与 SPT 保持一致
每行执行根据业务二选一通常选“只执行一次”,减少数据库压力

5. 避坑清单:存储过程不生效、ORA-01403 与事务错乱的排查顺序

5.1 存储过程调了几次,但目标表数据纹丝不动

现象:映射成功,日志里也看到了 SPT 执行信息,但目标表里该清的数据还在。

原因:最常见的是存储过程执行的事务没有被提交。存储过程内部没有COMMIT,而 Informatica 会话里的Commit on Success又恰好是关闭的,或者执行失败后框架自动回滚,导致存储过程的 DELETE 一直没有真正落库。

解决:先在数据库端手动执行一次存储过程,确认它本身没问题;再确认存储过程里是否带COMMIT。如果不想在存储过程里写事务,就把会话的 Commit on Success 打开。我个人的习惯是让存储过程自己负责任务完整性,因为 Informatica 的事务边界和数据库端过程的事务边界一旦交错,很容易出现“日志说成功,库里没变化”的灵异事件。

5.2 映射成功但日志里有 ORA-01403: no data found

现象:映射最终是成功的,但工作流日志里刷满了ORA-01403错误,有的版本会直接让会话失败,有的只是警告。

原因:存储过程内部用了SELECT ... INTO语句,但查询结果为空,存储过程没做异常捕获,异常一路抛到 Informatica 连接层。很多 PL/SQL 过程这么写,本质上写着“查不到就报错”,但 ETL 调用方并不希望一个正常流程里出现红色报错。

解决:和数据库开发约定好,存储过程内部必须捕异常并返回正常状态,或者至少用NO_DATA_FOUND做兜底。举个例子,改成:

BEGIN SELECT COUNT(*) INTO v_cnt FROM ORDERS_HIS WHERE biz_date = pi_date; EXCEPTION WHEN NO_DATA_FOUND THEN v_cnt := 0; END;

ETL 层不要尝试去“容忍”这种异常,因为你无法区分“查无数据”和“真异常”。

5.3 Informatica 端口类型和数据库参数类型不一致

现象:映射跑了一段时间突然失败,报错类似“ORA-06502: PL/SQL numeric or value error”,或者参数传进去后存储过程算出错误结果。

原因:端口类型定义得太随意。比如数据库存储过程的入参是NUMBER,映射里却用了 String 端口;或者数据库入参是VARCHAR2(3),映射端口默认的 String 是 255 位,把超长字符串直接传了过去。

解决:建端口之前,先查一下存储过程的元数据,确定每个入参的类型和长度,再逐一对照 Informatica 里的数据类型。最好建一个小的“参数映射表”放在项目文档里,避免三个月后改需求时忘了当初怎么对的。

5.4 SQLT 里加了分号导致语法校验失败

现象:新建 SQLT,SQL Query 写的是CALL PROC_NAME(:in_param);,点击确定时报语法错误。

原因:Informatica 的 SQLT 会把整段 SQL 直接交给数据库执行,但它的校验逻辑对分号非常敏感。

解决:去掉 SQL Query 末尾的分号,确认数据库端用 JDBC 或 ODBC 执行时不需要分号。还有一种情况是某些数据库方言确实要求分号,那就把它写到数据库的同义词/包装存储过程里,SQLT 里仍然不写。

5.5 上游字段为空导致存储过程入参变成 NULL,业务数据被清空

现象:目标表数据被大面积删除,而不是只删除当天的。

原因:pi_date参数是 NULL,存储过程里的 DELETE 条件变成了biz_date IS NULL或者因为空值判断问题,删错了范围。这种情况在 SPT 里特别容易踩:源表某行biz_date正好缺失,传递后参数为 NULL,数据库里 DELETE 又被写成了无条件删除最终版。

解决:在连到 SPT 之前,加一个表达式转换器,对入参做空值兜底。比如:

IIF(ISNULL(BIZ_DATE), TO_DATE('1970-01-01','YYYY-MM-DD'), BIZ_DATE)

设置成“空值不执行”也是一种办法,但统筹考虑,兜底值更符合 ETL 的习惯——宁可清掉一条无意义的数据,也不能让空参数引发全表误删。

6. 进阶技巧:游标回读、压力验证与一个收尾习惯

到这里,基础调用已经通了,但真实项目里还会有两个进阶要求:存储过程返回多行结果集并继续加工,以及如何确认这个方案在数据量上来之后依然撑得住。

先说游标回读。回到 SQLT 那节,如果 Oracle 存储过程返回的是SYS_REFCURSOR,你可以先在数据库端包一层函数,把游标包成流水线表,然后在 SQLT 里用SELECT * FROM TABLE(MY_FUNC(:pi_date))的方式读取。这是目前兼容性最好、也最容易维护的模式。如果你的数据库是别的厂商系,思路一样:让存储过程的调用结果表现为一张可查询的表,Informatica 只负责消费这张表。

再说压力验证。不要在测试环境用 100 行数据验证完就上生产。我通常会把数据量放到生产预估的 5 倍以上,然后用工作流监控看 SPT 的执行时间占比。如果发现存储过程执行占到了整个会话 80% 以上的时间,就要检查是不是数据库端缺索引,或者存储过程内部有全表扫描。Informatica 这边常见的优化方式是:把 SPT 从逐行调用改为批量调用,方法是给 SPT 配置“缓存”属性,让它按批次传入参数,减少过程调用的次数。这个属性在 SPT 的“属性”选项卡里,叫“缓存”相关设置,和 Source Qualifier 的缓存逻辑不完全相同,但思路一致。

最后说一个我自己的习惯:每次建完一个 SPT 或 SQLT,我都会在工作流里加一段探针日志,前移检查点。具体做法是,在调用步骤后增加一个“Post-成功检查”的脚本,比如统计目标表行数,发送到运维通知。这样一旦数据异常,第一时间看到的是“目标表行数= 0”而不是“过程调用成功”。

这么多年下来,我发现 Informatica 调存储过程真正难的地方从来不在配置界面上,而在你对事务边界、参数类型和异常处理这三件事有没有清醒的认识。把这几个点管住,这个方案就是稳定可靠的。希望帮到你。

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

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

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

立即咨询