资讯详情

资讯详情

Informatica Pre SQL调用存储过程:选型、参数与事务避坑

简介面向使用 Informatica 开展数据集成的初中级开发、运维与实施人员这份图文文档围绕调用存储过程的实现方式展开帮助读者理解在 Mapping 中结合 pre SQL 与变量传参完成存储过程调用的整体思路并可延伸至数据迁移、数据同步和报表生成等常见场景。压缩包内共 1 个 docx 文件约 180KB内容以图文结合的形式组织篇幅精简便于在项目实践中快速查阅和对照理解。目前已有 977 人学习说明其在同类操作参考中具备一定认可度。文档重点突出调用流程拆解与关键配置说明可帮助读者梳理存储过程调用的注意点也适合需要补齐 Informatica 相关知识点、提升数据集成实践能力的读者参考。对于需要快速定位调用要点、减少反复试错时间的开发者具有较高的参考价值。1. 目标表 Pre SQL 里塞一段存储过程先弄清它到底在什么时候跑很多人第一次做 Informatica 调用存储过程都是被需求推着走的源端逻辑早就封装在数据库的存储过程里ETL 侧不想重写一遍只想在加载前后顺手把这段逻辑触发一下。这时最省事的落点往往不是加 Transformation也不是写外部脚本而是打开 Mapping右键目标表 → Edit → 切到属性页在 Pre SQL 里写一行调用语句。这套做法在 Informatica PowerCenter 里确实成立也能跑通但它有一个隐藏前提——你得清楚 Pre SQL 挂在哪一层、什么时候执行、一次 session 执行几遍。我见过不止一个项目组把它当成万能钩子结果要么存储过程压根没跑要么重启一次 session 就重复处理了一遍数据。下面按照实际项目的拆解顺序从选型、写法、参数替换、事务提交一直讲到怎么验证面向的是手上已经有存储过程、需要在 ETL 流程里挂上去的从业者。2. 三条调用路径的选型Pre SQL、Post SQL 与 Stored Procedure Transformation2.1 为什么目标表 Pre SQL 成了默认落点Informatica 给存储过程留的入口其实不止一个但工程上真正被大量使用的就那么两三个。要理解为什么大家最后都落在目标表的 Pre SQL 上得先看清这四个挂载点的区别目标定义Target Definition里的 Pre SQL、目标定义里的 Post SQL、Session 属性里的 Pre-session SQL、Session 属性里的 Post-session SQL。前两个跟着目标表走粒度是「这个目标表在这一轮加载前/后」后两个跟着 session 走粒度是「这个 session 在整个流程前/后」哪怕这次一行数据都没进来也会执行。目标表 Pre SQL 之所以受欢迎原因很实在。第一它不需要改动 Mapping 的端口结构源到目标的字段映射原样保留DBA 写好并测试过的存储过程可以整段复用不需要在 ETL 侧再翻译一遍逻辑。第二它用的就是目标库的连接权限、schema、事务上下文全都对得上不会出现「存储过程在 ETL 连接下能跑、在别的连接下报权限不足」这种割裂。第三写起来确实短一行调用脚本加一个参数占位就完事交付时给运维看也清楚。代价同样明确。Pre SQL 是表级、批次级的钩子不是行级的。它拿不到 Source Qualifier 里的字段值也拿不到当前这一行的数据只能引用参数文件或 Session 参数里定义好的变量。如果你的存储过程需要「每来一行就带上这一行的主键调一次」那 Pre SQL 这条路从一开始就走不通必须换到 Stored Procedure Transformation 的 Run time 模式。我一般会先问一句这个存储过程是整批处理还是逐行处理整批就走 Pre SQL逐行才考虑 Transformation这条判断线能省掉后面一大半返工。还有一点常被忽略Pre SQL 的执行是有条件的。按我遇到过的几套环境当上游查询结果为 0 行、没有任何数据行进入目标表时目标级的 Pre SQL 通常不会触发。这跟很多人的直觉相反——大家默认「session 跑了Pre SQL 就该跑」。如果你的存储过程承担的是「每天清空汇总表并重算」这种无关于是否有增量数据的职责把它放在目标 Pre SQL 里就是个隐患遇到无数据的日期会静默跳过。2.2 Stored Procedure Transformation 的两个模式和六种调用时机当 Pre SQL 满足不了需求时第二个候选就是 Stored Procedure Transformation。它在 Mapping 里以组件形式存在分 Connected 和 Unconnected 两种用法差别很大。Connected 模式把它串在数据流中间有输入端口和输出端口要求存储过程返回单行单列的值这个返回值会被当成一列数据继续往下游流。它适合「调用一个函数算出一个值然后拿这个值参与后续转换」的场景比如根据批次号查出一个汇率或者一个维度代理键。如果存储过程返回的是结果集而不是单值Connected 模式会直接报错这条路就走死了。Unconnected 模式更灵活它不出现在数据流里而是在表达式转换Expression Transformation里以:SP.过程名(参数...)的形式被调用。同一个 Unconnected 过程可以在多个表达式里复用也可以配置成只调用一次然后把结果缓存起来给所有行使用。真正决定行为的是调用时机属性常见的有六种Always每次 session 运行都调一次、Source Pre load源读取前调、Source Post load源读取后调、Target Pre load目标加载前调、Target Post load目标加载后调、Run time每处理一行调一次。这六种时机配上 Connected/Unconnected基本覆盖了 90% 的调用需求。这里有个性能上的血泪经验Run time 模式是逐行调用一万行就是一万次数据库往返。我在一个项目里见过有人用它做逐行的编码校验测试环境两千行数据跑得挺快上生产三百万行直接跑到超时。逐行调用如果非要不可至少要在源端先做一次聚合或者去重把调用次数压到千级以内。2.3 选型对照表与两条判断线把几种方式的关键差异摆在一张表里选型时对照着看会快很多。方式触发粒度能否拿返回值能否引用行字段无数据时是否执行典型场景主要风险目标表 Pre SQL表级、加载前一次否否通常不执行整批预计算、清表、准备临时数据无数据静默跳过、重建无法回滚目标表 Post SQL表级、加载后一次否否视加载结果而定加载后打标记、写审计、刷新物化视图失败时可能不执行Session Pre-session SQL会话级、流程开始前否否执行批次初始化、控制表置位与目标表不在同一事务Stored ProcedureConnected按配置时机是单值是视配置取值参与后续计算返回结果集直接报错Stored ProcedureUnconnected Run time逐行是单值是视配置逐行校验、逐行取代理键行数大时性能崩塌Source Qualifier SQL Override 调过程源级视数据库否视查询数据库支持 SELECT 调用过程时方言差异大、可移植性差两条判断线我通常会先划出来。第一条存储过程是在做「整批的数据加工」还是「单条记录的取值」前者走 Pre SQL 或 Post SQL后者才考虑 Transformation。第二条这个钩子必须在「有数据」时才执行还是「每天必须执行」如果是后者就要从目标级 Pre SQL 挪到 Session 级的 Pre-session SQL或者单独拆一个只跑存储过程的「哑 session」用 Workflow 的连线控制先后顺序。这两条线划完方案基本就定了剩下的都是写法问题。3. 从 Mapping 到 Pre SQL把调用脚本一行行写对3.1 建 Mapping 前先定落点谁负责写目标表动手之前先想清楚一件事这个存储过程自己会不会写目标表这决定了 Mapping 的骨架怎么搭。情况一存储过程只做中间加工比如把明细汇总到一张临时表真正的目标表还是由 Informatica 的 Writer 写入。这种情况下 Mapping 是常规结构源表拖进来目标表拖进来字段一一连好Pre SQL 里只写一行调用让存储过程在加载前把临时表准备好。这是最顺的一种也是原始流程里默认的那种。情况二存储过程自己负责把结果写进最终目标表Informatica 只是负责触发它。这时 Mapping 里其实没有真正的数据流常见做法是用一个哑源比如只返回一行的系统表连一个哑目标靠这个哑目标的 Pre SQL 去触发存储过程同时在 Session 里把 Treat source rows as 设成 Data Driven 之外的常规值让这条哑记录能顺利「流」过去。如果不这么搭Pre SQL 有可能因为无数据而不触发。情况三存储过程既做加工又要求拿到 ETL 侧的某些运行时值比如本次 session 的起始时间。这种就得看这些值是「常量级」还是「行级」——常量级用参数文件塞进去行级就只能上 Transformation。先确定落点再画图比画到一半发现端口接不上再推翻重来省时间。3.2 打开目标属性的正确姿势与 Pre SQL 的方言骨架基础操作本身不复杂但每一步都有个容易点错的地方。打开 PowerCenter Designer进入 Mapping Designer新建一个 Mapping 并命名把源定义和目标定义分别拖进画布用连线工具把端口连上。然后右键目标定义选择 Edit在弹出的对话框里切到 Properties 选项卡。这个选项卡里能看到 Database name、Owner name、Table name、Target load type再往下就是 Pre SQL 和 Post SQL 两个输入框。Pre SQL 里写的就是调用脚本。不同数据库的调用方言差别不小这是最容易翻车的地方。下面给出三种常见数据库在 Pre SQL 里的写法骨架。-- Oracle过程调用必须包在 PL/SQL 块里结尾一个分号 BEGIN ETL_PKG.SP_DAILY_AGG($$P_BATCH_DATE); END; -- Oracle 若过程无入参 BEGIN ETL_PKG.SP_REFRESH_MV; END;-- SQL Server用 EXEC注意不要额外加分号 EXEC dbo.SP_DAILY_AGG batch_date $$P_BATCH_DATE-- DB2用 CALL字符串参数要带单引号 CALL ETLSP.SP_DAILY_AGG($$P_BATCH_DATE)这几段代码的逻辑很直接$$P_BATCH_DATE是一个 Session 参数占位符运行前由参数文件替换成真实日期字符串ETL_PKG.SP_DAILY_AGG是带 schema 前缀的存储过程名加上 schema 前缀可以避免因为连接用户的默认 schema 不同而找不到对象。参数说明上有两点要注意第一替换是字面量替换字符串类型的参数必须自己在脚本里补单引号否则替换后变成SP_DAILY_AGG(20240601)会报类型不匹配第二Oracle 的 PL/SQL 块必须用BEGIN ... END;包住并以分号结束而 SQL Server 的 EXEC 语句结尾加分号在某些版本上会报语法错误这两者的处理方式正好相反。如果你的逻辑有多条语句最稳妥的做法是把它们全部封进一个存储过程Pre SQL 里只留一行。Informatica 对多语句 Pre SQL 的处理依赖数据库驱动和版本分号分隔、换行、注释都可能成为解析失败的诱因。封成一个过程既规避了这些不确定性也让逻辑有版本记录改起来不用回头翻 ETL 配置。3.3 把入参换成变量参数文件、Mapping 参数与硬边界原始流程里提到「如果用到变量将入参替换为变量即可」这句话是对的但变量从哪来、怎么生效值得展开说清楚。Informatica 里能在 Pre SQL 中替换的变量主要是两类Session 参数和 Mapping 参数两者都写$$参数名的形式运行时由参数文件或 Session 属性提供值。参数文件是工程上最常见的做法一个 session 对应一个段落段落头是工作流名和 session 名的组合。[WF_DAILY_AGG.WF_DAILY_AGG.SESS_LOAD_AGG] $$P_BATCH_DATE2024-06-01 $$P_SCHEMAETLSP $$P_COMMIT_SIZE10000这段配置的逻辑是方括号里定位到具体的 session下面逐行给参数赋值等号两边不要有空格。参数文件在 Workflow Manager 里通过 Workflow 的属性指定路径Session 级别的参数会覆盖 Mapping 级别的同名参数。参数说明上$$P_BATCH_DATE的值会被原样字符串替换进 Pre SQL所以格式必须和数据库期望的日期格式一致Oracle 里写2024-06-01依赖会话的 NLS_DATE_FORMAT如果对方库的格式是YYYYMMDD最稳妥的方式是在存储过程内部做一次TO_DATE不要让 ETL 侧去赌格式。这里有一条必须记住的硬边界Pre SQL 里不能引用端口。Source Qualifier 的字段、Expression 的输出端口、Sequence Generator 生成的值全都进不去 Pre SQL因为 Pre SQL 是在目标加载动作发生之前由 session 直接下发给数据库的那时行数据还没组织好。想让存储过程拿到某一行里的字段只有两条路可走改用 Stored Procedure Transformation 的 Run time 模式或者让 ETL 先把这些值写进一张参数表存储过程自己去读。后者看着绕但在批量场景里反而更稳因为它把「传参」变成了「传数据」可以一次带上千行参数。还有一点Session 参数可以来自参数文件也可以在 Session 属性里直接写死默认值。我给团队定的规矩是凡是会随批次变化的一律走参数文件只有跨环境不变的东西比如 schema 名才写死。这样换环境时只改一个文件不用满仓库找配置。3.4 保存之后Session 里到底生成了一条什么语句点确定、保存回到 Repository Manager 里把 Mapping 提交然后在 Workflow Manager 里新建 Session 并挂上这个 Mapping。这一步做完之后建议进 Session 属性里翻一遍Mapping 里目标定义的 Pre SQL 会随 Mapping 一起带进 Session不需要在 Session 里再写一遍。Session 属性里另有 Pre-session SQL 和 Post-session SQL 两个框名字很像位置不同作用域也不同别写串了。运行时序大致是这样Session 启动 → 源连接建立、执行源查询 → 转换逻辑逐行计算 → 目标连接建立 → 下发目标 Pre SQL → 批量写入目标 → 下发目标 Post SQL → 提交事务。当你在 Session 日志里看到类似PRE STATEMENT或WRT_xxxx的条目时后面跟的那条语句就是实际下发的调用脚本被替换掉的参数也会出现在日志里。这是后面排查问题最重要的一手证据。4. 参数与事务入参、出参与提交粒度的实操参数表4.1 入参来源对照源字段、参数文件、数据库函数入参这件事在 Pre SQL 方案里其实只有一种合法来源——参数。但参数本身可以有多种填法选哪种取决于参数的「变化频率」和「来源位置」。入参来源写法生效时机适合的参数不适合的参数参数文件$$P_NAME 文件段落Session 启动时读取批次日期、跑批号、环境标识行级字段、运行时聚合值Session 属性默认值$$P_NAME 属性框Session 启动时生效schema 名、固定阈值每天变化的值数据库函数取当前值SYSDATE/GETDATE()直接写在脚本里SQL 下发时由库计算执行时间戳、当前日期需要与 ETL 批次对齐的日期参数表存储过程自己查参数表过程内部读取多参数、批量参数、可变参数集极简场景增加一张表表里最值得说的是最后一行。当参数超过三四个或者参数本身是一批编码清单参数文件就会变得难维护。这时更常见的做法是让 ETL 先把参数落到一张控制表存储过程开头自己去读。好处是参数有历史记录、可以追溯某个批次用的是哪版参数坏处是多了一次数据库交互而且控制表的写入必须在 Pre SQL 之前完成通常得放到上一个 session 的 Post SQL 里。我一般会把这套东西和后面的审计日志合并设计一张表同时记录参数和调用结果省事。另外提醒一个细节参数名的大小写。Informatica 的参数名$$P_BATCH_DATE和参数文件里的写法必须完全一致参数文件里写$$p_batch_date在某些版本上不会报错只是替换不上SQL 里就留着字面量$$P_BATCH_DATE原样发给数据库最后报一个「无效的日期格式」或者「标识符过长」。这类报错看起来像语法问题实际上是参数没替换排查时要先看日志里的实际语句别一上来就改 SQL。4.2 出参为什么拿不到Pre SQL 的硬边界与两条折中路线存储过程经常需要返回一个结果比如处理了多少行、有没有校验失败、生成的批次号是多少。在 Pre SQL 里这个返回值是没有地方接的——它不像 Stored Procedure Transformation 有输出端口Pre SQL 执行完就结束了返回值被丢弃。如果这个返回值只是用来做审计最简单的方式是让存储过程自己往日志表里写一条记录Pre SQL 完全不管。如果这个返回值必须参与 ETL 后续的判断比如校验失败时让 session 直接失败那就有两条折中路线。第一条是控制表加 Post SQL 检查。存储过程把执行结果写进控制表ETL 在其后接一个 Session读控制表里的状态字段用 Source Qualifier 的过滤条件把失败记录放出来再用一个非空的哑目标触发失败从而让 Workflow 走到失败分支。这条路线整个流程都在 ETL 里闭环缺点是链路变长。第二条是改用 Stored Procedure Transformation 的 Connected 模式把返回值直接接成一个端口在后面的 Expression 里做判断再通过ABORT()函数中断 session。这条路线干净代价是存储过程必须改造成返回单值如果原过程返回的是结果集就得再加一层包装。我通常选第二条因为它的失败信息能直接进 Session 日志运维一眼能看到原因。但前提是 DBA 愿意配合加一个只返回单值的包装过程这个协调成本要提前算进去。4.3 提交粒度SP 里的 COMMIT 为什么会把 session 拖下水事务这块是最容易埋雷的地方。Informatica 在 Target load type 为 Normal 时自己管理事务它会按照 Commit Interval 的设置分批提交。如果存储过程内部自己COMMIT了就会把 session 还没提交的那部分事务一起提交掉直接后果是——加载中途失败时前面的部分数据已经落库回滚不回去目标表处于半截状态。更隐蔽的是锁的问题。如果存储过程在 Pre SQL 里对目标表做了一次大范围 DELETE 并提交而 session 紧接着要往这张表插数据两边的事务在同一个连接上串行看起来没问题但如果这张表还有别的 session 在读写就可能出现长时间的锁等待Session 日志里冒出锁超时或者死锁的消息表现为「跑着跑着卡住」。我的处理原则是Pre SQL 调用的过程里一律不写 COMMIT事务边界交给 Informatica 管。如果过程内部的逻辑确实需要分段提交比如一次性处理上百万行那就把它从 Pre SQL 挪出去做成独立的 session 或者独立的步骤在 Workflow 里串行排在主加载之前让它有自己的连接和事务边界。这样即使它提交了也只影响自己不会污染主流程的事务。还有一个小参数值得调Commit Interval。默认值在大批量场景下偏大一旦失败回滚的代价高设置成几千到一万之间配合不写 COMMIT 的存储过程重跑时的清理成本能明显下降。这个值没有通用答案我一般按目标表的行宽和目标库的 undo 空间来估先在测试环境跑一轮看 undo 增长曲线再定。5. 踩坑排查调用不生效、报错与重复执行的五条血泪经验5.1 报错类方言与权限的三次翻车现象一Session 运行失败日志里报 ORA-06550 或 SQL Server 报 Incorrect syntax near ;。原因通常出在 Pre SQL 的语句结束符上。Oracle 的过程调用必须整段包在BEGIN ... END;里如果只写ETL_PKG.SP_DAILY_AGG(2024-06-01);这一行PL/SQL 引擎会认为块不完整而 SQL Server 的 EXEC 语句末尾多写一个分号某些驱动版本会把它当成第二个空语句。还有一种情况是复制粘贴时带进了不可见字符或者全角空格。 解决方式是把脚本压到最短Oracle 用BEGIN 过程名(参数); END;SQL Server 用EXEC 过程名 参数写完先在数据库客户端里原样跑一遍确认能过再填进 Pre SQL。填的时候不要从 Word 里粘从纯文本编辑器走一道。现象二日志报对象不存在或者权限不足但同一个用户在客户端里能正常执行。原因是 Informatica 用的连接用户和你测试时用的不是一个账号或者连接串指向的库不同。另一个常见原因是过程名没写 schema 前缀Informatica 连接的默认 schema 和你的测试账号不一样导致解析到了别的 schema 下。 解决方式是先在存储过程名前面补全 schema例如ETL_PKG.SP_DAILY_AGG然后到目标库上确认 ETL 连接用户对这个过程有 EXECUTE 权限对过程内部涉及的表有相应 DML 权限。注意存储过程是以定义者权限还是调用者权限执行这两种模式下需要的授权完全不同这一点要跟 DBA 确认清楚。5.2 语义类不执行与重复执行的判别现象三Session 显示成功日志里也有 PRE STATEMENT但存储过程的效果没出现。先分清两种可能。一种是 Pre SQL 根本没执行当上游查询结果为 0 行时目标级的 Pre SQL 通常不触发而 Session 依然记为成功日志里那行 PRE STATEMENT 可能只是编译信息。另一种是执行了但效果被覆盖存储过程往目标表写了数据紧接着 Informatica 的 Writer 用 Truncate target table 选项把表清空了或者 Update Override 把数据覆盖了。 解决方式分两步查。第一步在 Pre SQL 里加一条「打点」语句比如往控制表插一行带批次号的记录跑完看这张表有没有新行能立刻区分是没执行还是执行了被覆盖。第二步检查目标定义的 Truncate target table option 和 Session 的 Treat source rows as 设置确认加载方式不会把过程的结果冲掉。现象四重跑一次 session数据翻倍或者指标被重复累加。这是最典型的一类。Pre SQL 在 session 恢复运行时会被再次执行而存储过程如果没有做幂等处理就会把同一批次的数据再算一遍。按 Recovery strategy 配置不同有时候是从失败点继续有时候是整个 session 重跑但 Pre SQL 都会再走一次。 解决方式是把存储过程改造成幂等开头先按批次号删掉本批次已有的结果再插入或者在控制表里判断这个批次是否已经处理过、处理过就直接返回。我对所有挂在 Pre SQL 上的过程都强制加这一层宁可多一次 DELETE 的开销也不要事后去对账修数据。5.3 并发类锁等待与提交粒度的连锁反应现象五Session 长时间停在执行阶段日志最后报锁等待超时或死锁。原因有两层。表层是存储过程在 Pre SQL 里对目标表做了大范围 DML 且没有及时释放锁而同一时间别的流程正在读写这张表。深层是事务边界不清过程内部提交了Informatica 那边以为事务还在自己手里两边对同一批行的锁期望不一致。 解决方式是拆。把重度的数据加工从 Pre SQL 挪到独立的 session在 Workflow 里用连线控制它跑在主加载之前让它有独立连接、独立事务跑完提交再进入主流程。如果暂时不能拆至少把过程中的 COMMIT 去掉让事务由 Informatica 统一管理同时把 Commit Interval 调小缩短单次持锁时间。判断是否修好看两个指标Session 日志里目标表相关的等待时间以及数据库侧的锁等待统计两个都降下来才算真解决。6. 验证与进阶用控制表和幂等改造把这段流程钉死存储过程挂上去能跑通只是第一步。真正让人睡得着觉的是出问题时能三分钟内说清楚「跑了没有、跑了几次、影响多少行」。我的做法是强制要求每个挂在 Pre SQL 上的过程都往一张控制表写记录字段至少包括批次号、过程名、开始时间、结束时间、影响行数、状态。这一条记录就是黑匣子对账、排障、复盘全靠它。-- 控制表结构以 Oracle 为例其他库按方言调整类型 CREATE TABLE ETL_PROC_LOG ( BATCH_NO VARCHAR2(20), -- 批次号与 ETL 参数同源 PROC_NAME VARCHAR2(64), -- 存储过程名 START_TIME DATE, -- 过程开始时间 END_TIME DATE, -- 过程结束时间 AFFECTED_ROWS NUMBER, -- 影响行数 STATUS VARCHAR2(10) -- RUNNING / SUCCESS / FAILED );这段建表语句的重点在BATCH_NO和PROC_NAME的组合它天然构成一个可以反复查的键。存储过程开头插一条 RUNNING结尾更新成 SUCCESS 并回填行数异常分支更新成 FAILED 并记录错误码。之后每次怀疑「到底跑没跑」一条SELECT * FROM ETL_PROC_LOG WHERE BATCH_NO ...就够不用去翻几百兆的 Session 日志。配套的幂等改造也简单过程入口先查这张表里同批次同过程是否已经是 SUCCESS是就直接 RETURN不是才继续往下走。这一层判断能挡掉绝大部分因为重跑导致的数据翻倍。-- 幂等入口判断示意放在过程最前面 SELECT COUNT(*) INTO V_CNT FROM ETL_PROC_LOG WHERE BATCH_NO P_BATCH_NO AND PROC_NAME SP_DAILY_AGG AND STATUS SUCCESS; IF V_CNT 0 THEN RETURN; -- 本批次已成功处理直接退出避免重复累加 END IF;V_CNT是本地变量P_BATCH_NO是过程的入参由 Pre SQL 里的$$P_BATCH_DATE替换后传入。这段代码的作用是在过程执行任何业务逻辑之前做一次短路判断成本是一次索引查询收益是重跑安全。注意这里判断的是 SUCCESS 而不是存在记录因为失败重跑是正常需求只有成功过的批次才需要跳过。验证环节我一般会做三处对账控制表里的记录条数与 Workflow 里该 session 的运行次数是否一致控制表里回填的影响行数与目标表的实际增量是否吻合Session 日志里 PRE STATEMENT 后面那条语句里参数是否被替换成了正确的值。三处都对上这段流程才算真的钉住了。最后说个习惯。早些年我在一个批量项目上吃过亏存储过程挂在目标 Pre SQL 上跑了小半年都正常直到某天上游没有增量数据整个过程静默跳过下游报表空了一整天而 session 状态全是成功。从那以后我每次把存储过程挂到 Pre SQL 之前都会强制走一遍「空数据日」的测试故意把源查询过滤成 0 行看这个过程还跑不跑、控制表有没有记录。这一步花不了十分钟但能提前暴露一类最难在生产上复现的问题。相关的图文操作步骤和参数文件模板我整理在一起了对着走一遍比从零摸索快不少。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →