将空值传递给 OData V2 Edm.Time 属性

Pass an empty value to an OData V2 Edm.Time property

我有一个变量类型 time 但有时这个变量没有任何东西。

当它是初始值时,它不应该是 "000000",我想要一个没有任何东西的空值(没有零)。让我用代码解释我的问题:

IF lwa_hora IS INITIAL.
   CLEAR lwa_hora.
   ls_entity-hora = lwa_hora. " Result: 000000 but I don't want any zero
ELSE.
   ls_entity-hora = lwa_hora. " Result: 000000
ENDIF.

我试过 CLEAR 但没有任何反应。

我需要这个是因为在 JavaScript 前端客户端逻辑中,我需要 OData 属性 包含虚假值(例如 null 或空字符串 "").

但它始终具有值 "000000",即 而不是 空字符串。是否可以在后端做一些事情来“清除”变量?

abap (t) 中的时间数据类型是值类型。它在内部实现为一个整数,计算自午夜以来的秒数。自午夜起 0 秒是一个有效值,因此它不能有空值。

但是,ABAP 允许您创建对任何值类型的引用:

hora TYPE REF TO t.

这意味着 hora 将是对 TYPE t 变量的引用。最初,此引用将是未绑定的,这在概念上与其他编程语言中的空引用非常相似。您可以通过以下方式检查:

IF ls_entity-hora IS BOUND.
...
IF ls_entity-hora IS NOT BOUND.

您可以使用 GET REFERENCE OF lwa_hora INTO ls_entity-hora 分配时间值。但是现在您有一个对现有变量的引用。改变lwa_hora的值,ls_entity-hora的值也会改变。那可能并不总是你想要的。所以最好在内存中新建一条数据供我们引用指向:

CREATE DATA ls_entity-hora.

现在 ls_entity-hora 不再是未绑定的(或者“空”,如果你想这样称呼它的话),它指向一个新的时间值 000000。如果你想读取或更改这个引用指向的这个无名数据的值,那么你可以使用取消引用运算符 ->*:

ls_entity-hora->* = lwa_hora.

如果您有意将引用设置为未绑定(或“将引用设置为空”),您可以通过清除引用来实现:

CLEAR ls_entity-hora.

顺便说一下:在过去十年中,用 dt 类型的两个独立变量表示时间点已经过时了。当前针对这种情况的最佳做法是使用类型为 TIMESTAMP(如果需要秒级精度)或 TIMESTAMPL(如果需要微秒级精度)的单个变量。 00000000000000 的时间戳显然是非法值,因此可以用来表示时间点的缺失。这种类型通常还可以更轻松地与 SAPUI5 前端进行通信(就像您的情况一样),因为许多用于制作 oData 服务的技术都提供 Javascript Date 和 ABAP [=26= 之间的自动转换].

堆分配时间的另一种方法是在它旁边存储一个布尔值,指示它是否已设置:

TYPES:
     BEGIN OF optional_time,
        time    TYPE t,
        is_null TYPE abap_bool,
     END OF optional_time.

DATA(no_time) = VALUE optional_time( is_null = abap_true ).

" Setting to null:
DATA(some_time) = no_time.
" Setting to some time:
some_time = VALUE #( time = '12:30' ).

IF some_time = no_time.
   " ...
ENDIF.

这种事情在前端处理可能比在后端处理更好。

如果对应的 属性 可为空,则 SAP Gateway 在 OData 响应中将 ABAP Date/time 初始值序列化为 NULL。您需要确保此 属性 设置为 TRUE,就像此示例中的

你也可以在运行时设置这个属性

TRY .
 lo_action = model->get_entity_type( iv_entity_name = 'Z_REPORTType').                                                             
 lo_property = lo_action->get_property( iv_property_name = 'Requested_Date').
 lo_property->set_nullable( iv_nullable = abap_true ).
CATCH /iwbep/cx_mgw_busi_exception /iwbep/cx_mgw_med_exception /iwbep/cx_mgw_tech_exception INTO DATA(lo_exception).
ENDTRY.