SELECT FROM @itab 语句介绍

举报
雨绸缪 发表于 2023/07/31 17:13:00 2023/07/31
【摘要】 介绍除了常规的 SELECT FROM table 语句,ABAP 还提供了支持在变量前加入 @ 符号的查询方法。指定一个内部表 itab,其名称必须以 @ 字符为前缀,作为查询的数据源。SELECT 语句处理应用服务器的内部表,就像数据库中的数据库表一样。内部表中列的 ABAP 类型被映射到 ABAP 字典中合适的内置数据类型。如果一个列在声明时参考了 ABAP 字典中的一个类型,那么这...

介绍

除了常规的 SELECT FROM table 语句,ABAP 还提供了支持在变量前加入 @ 符号的查询方法。

指定一个内部表 itab,其名称必须以 @ 字符为前缀,作为查询的数据源。SELECT 语句处理应用服务器的内部表,就像数据库中的数据库表一样。内部表中列的 ABAP 类型被映射到 ABAP 字典中合适的内置数据类型。如果一个列在声明时参考了 ABAP 字典中的一个类型,那么这个类型就被直接使用。

这里有两种不同的情况:

  • 内部表的数据在数据库中是不需要的。
    在这种情况下,内部表的数据在应用服务器上被访问,并且该表像表缓冲器中的表一样被处理。这对所有的数据库平台来说都是可能的。
  • 内部表的数据在数据库上是需要的。
    在这种情况下,数据必须在查询实际执行前传递给数据库中的临时表。这个选项不是所有数据库都支持的。如果静态地知道数据在数据库中是必需的,就会出现一个语法检查警告,可以通过模式##db_feature_mode[itabs_in_from_clause] 隐藏。如果在运行时试图将数据从内部表传递到数据库,而数据库不支持这样做,就会产生一个 CX_SY_SQL_UNSUPPORTED_FEATURE 类的可处理异常。

恰恰是在 SELECT 语句满足与表缓冲区访问时相同条件的情况下,内部表中的数据不得传递给数据库(或者语句可以在应用服务器上执行)。

内部表中的列的 ABAP 类型被映射到 ABAP 字典中的类型。如果一个列被声明为参考 ABAP 字典中的类型,则直接使用该类型。

以下条件适用:

  • 一个 Open SQL 语句中只能指定一个内部表。

  • 必须使用 AS 为内部表指定一个替代表名。

  • 内部表的行类型可以是基本的或结构化的。

  • 不允许有深度的行类型。一个基本的行类型不能是字符串或引用类型,一个结构化的行类型不能包含任何字符串,引用类型,或内部表作为组件,但有以下例外:如果使用对内置字典类型SSTRING的引用来声明一个基本的行类型或具有字符串类型的组件是允许的。

  • 如果使用附加的 ORDER BY PRIMARY KEY,内部表必须有一个主表键。

  • 内部表的主表键的关键字段必须是连续的列,在行类型的开始处以相同的顺序出现。

  • 如果 FROM 子句是静态指定的,内部表不能是一个通用类型的形式参数或通用类型的字段符号。像这样的对象只能在动态的 FROM 子句中指定,并且必须在运行时代表一个匹配的内部表。

  • 内部表不能包含任何引用过时的字典类型 DF16_SCLDF34_SCL 声明的列。

  • 内部表应该有一个明确定义的主键(可以是空的)。通用的主键和标准键在读取时不会被评估,并出现语法检查警告。

内部表中的数据被处理得像数据库中的数据,即使它没有被传送到数据库中。特别是,使用对内置字典类型 SSTRING 的引用来声明的字符串类型的数据,被处理成具有固定长度的文本字段,其中尾部的空白被忽略了。

使用一个随机数表作为 SELECT 语句的数据源。数据被传送到数据库中进行排序,该语句只能在支持排序的数据库系统中执行。

TYPES:
  BEGIN OF line,
    id     TYPE c LENGTH 1,
    number TYPE i,
  END OF line.

DATA itab TYPE HASHED TABLE OF line
          WITH UNIQUE KEY id.

IF NOT cl_abap_dbfeatures=>use_features(
         EXPORTING
           requested_features =
             VALUE #( ( cl_abap_dbfeatures=>itabs_in_from_clause ) ) ).
  cl_demo_output=>display(
    `System does not support internal tables as data source` ).
  RETURN.
ENDIF.

DATA(rnd) = cl_abap_random_int=>create(
  seed = CONV i( sy-uzeit ) min = 1 max = 100 ).
itab =  VALUE #(
  FOR i = 1 UNTIL i > 25
  ( id = substring( val = sy-abcde off = i len = 1 )
    number = rnd->get_next( ) ) ).

SELECT *
       FROM @itab AS numbers
       WHERE number > 50
       ORDER BY id
       INTO TABLE @DATA(result)
       ##db_feature_mode[itabs_in_from_clause].

cl_demo_output=>display( result ).

使用一个内部表作为 SELECT 语句的内部连接的数据源。数据被传送到数据库进行连接,该语句只能在支持连接的数据库系统中执行:

DATA itab TYPE HASHED TABLE OF scarr
          WITH UNIQUE KEY mandt carrid.

IF NOT cl_abap_dbfeatures=>use_features(
         EXPORTING
           requested_features =
             VALUE #( ( cl_abap_dbfeatures=>itabs_in_from_clause ) ) ).
  
  cl_demo_output=>display(
    `System does not support internal tables as data source` ).
  RETURN.
ENDIF.

itab =  VALUE #( ( carrid = 'LH' carrname = 'L.H.' )
                 ( carrid = 'UA' carrname = 'U.A.' ) ).

SELECT scarr~carrid, scarr~carrname, spfli~connid
       FROM @itab AS scarr
         INNER JOIN spfli ON scarr~carrid = spfli~carrid
       INTO TABLE @DATA(result)
       ##db_feature_mode[itabs_in_from_clause].

cl_demo_output=>display( result ).

使用一个具有基本数据类型的表作为两个 SELECT 语句的数据源。数据库上不需要这些数据,而且 SELECT 语句符合表缓冲的要求。这意味着这些语句可以在所有数据库系统上执行。在第二条 SELECT 语句中,如果没有替代列名号,就会出现语法错误,因为 INTO 后的内联声明不能创建列名为 table_line 的内部表。如果这些语句被修改得不再符合表缓冲的要求(例如增加了 DISTINCT ),那么就不可能在所有数据库系统上执行。

DATA itab TYPE SORTED TABLE OF i WITH UNIQUE KEY table_line.
itab =  VALUE #( ( 1 )
                 ( 2 )
                 ( 3 ) ).

DATA result1 LIKE itab.
SELECT table_line
       FROM @itab AS numbers
       INTO TABLE @result1.
cl_demo_output=>write( result1 ).

SELECT table_line AS number
       FROM @itab AS numbers
       INTO TABLE @DATA(result2).
cl_demo_output=>display( result2 ).
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。