问题解决 SLT 写入数据库 NULL 值

作者:ABAP技巧与实战 约 9 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, Data Engineering, WM, 仓库管理, 开发, 数据工程
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

原创 无峰 [ ABAP 技巧与实战 ](javascript:void\(0\);)

前言

最近项目上使用SLT(SAP Landscape Transformation,是一个实时数据复制工具,主要用于将数据从源系统(如SAP

ERP或非SAP系统)复制到目标系统)把SAP数据同步到ORACLE数据库. 碰到初始化日期需要写入ORACLE数据库NULL值的问题

本文主要介绍SLT写入ORACLE数据库NULL值的方法

本文主要处理SAP空日期写入ORACLE数据库NULL值.其它类型可以参照实现

> 日期写入ORACLE还需注意,详见连接

>

> 无峰,公众号:ABAP 技巧与实战 [ 问题解决 SLT同步日期格式字段

> ](https://mp.weixin.qq.com/s/qOUBkjwMziI4cmimLqHtmQ)

日期初始值

SAP中日期的初始值 00000000 ,该日期无法写入ORACLE的日期字段. 用户希望当SAP日期是初始值时, 写入ORACLE日期字段NULL值.

日期00000000 SLT传输到目标日期类型的字段中时,报错 DMC_RT_MSG167

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

通过SM21查找具体SQL错误 ORA-01843 NOT A VALID MONTH

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

关于NULL值

ABAP中NULL值的相关信息

ABAP环境的数据定义不允许NULL值

SE11定义数据字典时, 有个初始值选项. 但似乎勾选无效

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

通过显示表的数据库对象, 可以看到, 不管数据字典SE11中是否勾选初始值, 产生的HANA数据库中的字段都不支持初始值

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

ABAP中NULL值的产生原因一

一般情况下,视图LEFT JOIN 的右表,如果没有记录, 会生成NULL值, 此时需要通过语句 IS NULL 去访问

比如EXORD 是关联右表的字段. EXORD IS NULL ,通过 EXORD = '' 无法访问到数据

视图中消除NULL值

可以通过 COALESCE(spfli.distance, 0) as distance_with_default 设置NULL的默认值

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

ABAP中NULL值产生原因二

表新增了字段,新增字段的内容系统设置为NULL值.

SLT对NULL值的支持

如NOTES 2684480所述, SLT不支持从 SAP system 同步到ORACLE 表字段NULL值

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

分析

SLT究其根本, 有如下处理逻辑

• 获取源系统的数据变化

• 从源系统读取变化的数据

• 写入目标系统

尝试找到写入目标系统的代码,研究调整使其支持写入NULL值即可.

方法

通过修改SLT写入程序实现NULL值写入ORACLE数据库

找到SLT配置的同步表(TCODE: LTRC)

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

双击查看生成的对象( 需要注意的是: SLT初始化过程生成一个函数组,初始化后会删除之前的函数组,生成一个新的函数组. 最好源表数据为空,

让SLT快速初始化通过,生成最终执行的函数组, 在这个函数组的写入函数中修改代码. 下面的代码修改也支持初始化的函数组中的函数修改.

源表数据非空的情况下,需要两次修改函数 )

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

对应的函数代码.

这里区分了 写入,更新,删除三个部分.图示了更新部分

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

** 同义词 **

这里有个奇怪的地方: 同步的表 ZTTS_SLT . ORACLE中也创建了ZTTS_SLT . 但是生成的函数中写入的表是

/1LT/10000000389

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

'/1LT/10000000389' 是表的ZTTS_SLT的同义词. SLT 为了使用OPEN SQL 更新ORACLE表, 采用了同义词.

该同义词在SE11中存在表,但是数据库定义不同于SE11定义

如下图是 SE11(SLT中) 定义 和 SLT数据库中定义 及 ORACLE表定义的区别. 看起来SLT定义同义词的目的是为了使用OPEN

SQL语句操作目标ORACLE数据库表

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

技术难点

ORACLE支持的最小日期是 00010101 . 尝试写入00000000会报错.

因此调整标准代码中写入,更新部分的内容00000000->00010101

标准程序写入数据后, 再把所有00010101的字段通过NATIVE SQL 更新成 NULL值.

** 思路比较简单,但具体实现NATIVE SQL 执行动态SQL却费了很大的功夫 **

最终发现, 只有通过调用存储过程, 才能实现动态UPDATE 语句

过程如下

1\. ORACLE中创建存储过程

CREATE OR REPLACE PROCEDURE execute_dynamic_sql (

p_sql_statement IN VARCHAR2)

IS

BEGIN

EXECUTE IMMEDIATE p_sql_statement;

EXCEPTION

WHEN OTHERS THEN

ROLLBACK;

RAISE;
END execute_dynamic_sql;

2\. ABAP中动态生成SQL语句,调用存储过程

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

为何不使用ADBC

NATIVE SQL动态更新数据碰到了很多麻烦. 在无数次和AI的沟通中, AI都建议使用ADBC实现动态语句更新数据(实现简单)

但因为标准生成的代码

insert /1lt/10000000389 client specified connection (con_name) 已经创建了一个数据库连接.

commit connection (con_name).

NATIVE SQL 可以直接使用这个连接

exec sql.

SET CONNECTION :con_NAME

endexec.

但是ADBC需要创建自己的连接.

在提交前创建连接会失败.

但如果放到提交后再更新. 更新为NULL值的语句和写入语句就不再一个事务中. 这样会导致其它系统可能会读取到 00010101 的初始化日期.

最终实现

封装类 ZCL_SLT_WRITE_DATUM_NULL

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

类构造方法中读取传入表的字段

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

CONVERT_DATUM方法负责动态把所有日期字段为00000000的转换成 00010101

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

UPDATE_NULL 负责在标准程序提交前,构造动态SQL把日期00010101更新成NULL值

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

标准写入函数的修改

在函数开始时替换传入的数据内容,需要考虑替换写入表和更新表

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

在提交数据库之前先更新数据为NULL

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

实测通过

测试表ZTTS_SLT中新增或修改的记录的空日期,写入ORACLE系统值为NULL

问题解决 SLT 写入数据库 NULL 值 - 封面图
问题解决 SLT 写入数据库 NULL 值 - 封面图

十一

总结

SLT把初始化日期写入目标ORACLE数据库NULL值,无法通过标准功能实现. 需要通过重写SLT生成的数据库写入函数.

因为该函数在配置LTRC时生成,并且生成的函数名可能与开发系统不一致. 所以需要在生产系统中直接修改函数,添加相关代码实现更新NULL值

SLT生成的写入目标数据库的代码没有使用ADBC的方法. 可能的原因

• 性能考虑, NATIVE SQL 性能可能好于ADBC

• 版本原因,SLT最初版的产品可能还无法使用ADBC

感觉可以在这里改进一下, 改用ADBC,同时预留出口, 以便客户实现更多样化的目标数据库内容写入

SLT 初始化对象是会生成一个函数组.初始化后会生成另外一个函数组.

SLT全局类型映射可能会导致在目标数据库创建表失败. (不确定这个BUG新版本是否修复). 最好使用表+字段级别的类型映射

** THE **

** END **

** 约定 **

如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.

请微信联系管理员

syjf1976

sharry_xlp

Yannick_Duan

申请进入公众号讨论群提问或者参与话题讨论

ABAP技巧与实战

关于作者:ABAP技巧与实战

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「问题解决SLT写入数据库NULL值.md」整理生成,仅用于内部技术分享与学习交流。