范围 table 和 IN 行为不正常
Range table and IN not behaving properly
即使 lt_spfli 不正常,如果 Carrid 正常,程序也会选择所有内容。并且没有任何带有该carrid的条目,它会出现运行时错误。如果我尝试所有条目,他只会选择整个 SFLIGHT。
PARAMETERS: pa_airp TYPE S_FROMAIRP,
pa_carid TYPE S_CARR_ID.
DATA: lt_spfli TYPE RANGE OF SPFLI,
lt_sflight TYPE TABLE OF SFLIGHT.
SELECT CONNID FROM SPFLI
INTO TABLE lt_spfli
WHERE AIRPFROM = pa_airp.
SELECT * FROM SFLIGHT
INTO TABLE lt_sflight
WHERE CARRID = pa_carid AND CONNID in lt_spfli.
使用 FOR ALL ENTRIES
而不是 CONNID in lt_SPFLI
。
这样:
SELECT *
FROM sflight
FOR ALL ENTRIES IN lt_spfli
WHERE carrid = pa_carid
AND connid = lt_spfli-connid
我只是想,您希望从给定机场出发的每个航班转机...
注意,RANGE
结构在实际的 "compare value" 前面还有两个字段。所以直接选进去会导致很乱table。
可能的解决方案:
选择RANGE
如果您真的想使用这个临时 table,您可以看看我的回答 ,我在其中描述了无需任何开销即可填充 RANGE
的方法。完成此步骤后,您当前的代码段也将按照需要的方式工作。请确保它确实已被填充,否则所有内容都会被选中。
选择 FOR ALL ENTRIES
在使用此变体之前,您应该绝对确定您指定的数据对象已填充。否则它会导致与第一个解决方案相同的混乱。为此,您可以这样写:
* select connid
IF lt_spfli[] IS NOT INITIAL.
* select on SFLIGHT
ELSE.
* no result
ENDIF.
选择 JOIN
在这种情况下 "correct" 方法将是 JOIN
如:
SELECT t~*
FROM spfli AS i
JOIN sflight AS t
ON t~carrid = @pa_carid
AND t~connid = i~connid
INTO TABLE @DATA(li_conns)
WHERE i~airpfrom = @pa_airp.
您误解了“范围 Table”是什么。你填错了。
你的这部分代码证明了误解(稍加调试,你会立即看到错误的内容):
DATA: lt_spfli TYPE RANGE OF SPFLI.
SELECT CONNID FROM SPFLI INTO TABLE lt_spfli ...
“范围 Table”是一个内部 table,具有 4 个组件(SIGN、OPTION、LOW、HIGH),在 Open SQL 中用于在一个数据库上进行复杂的选择列(注意:它也可以用在多个 ABAP 语句中以测试 ABAP 变量的值)。
因此,使用您的 SQL 语句,您仅初始化范围 table 的第一个组件,而您应该将 CONNID
转移到第三个组件。
在“现代”中打开 SQL,你最好这样做:
SELECT 'I' as SIGN, 'EQ' as OPTION, CONNID as LOW FROM SPFLI INTO TABLE @lt_spfli ...
关于范围Table的更多信息,您可以参考这里的答案:What actually high and low means in a ranges table
即使 lt_spfli 不正常,如果 Carrid 正常,程序也会选择所有内容。并且没有任何带有该carrid的条目,它会出现运行时错误。如果我尝试所有条目,他只会选择整个 SFLIGHT。
PARAMETERS: pa_airp TYPE S_FROMAIRP,
pa_carid TYPE S_CARR_ID.
DATA: lt_spfli TYPE RANGE OF SPFLI,
lt_sflight TYPE TABLE OF SFLIGHT.
SELECT CONNID FROM SPFLI
INTO TABLE lt_spfli
WHERE AIRPFROM = pa_airp.
SELECT * FROM SFLIGHT
INTO TABLE lt_sflight
WHERE CARRID = pa_carid AND CONNID in lt_spfli.
使用 FOR ALL ENTRIES
而不是 CONNID in lt_SPFLI
。
这样:
SELECT *
FROM sflight
FOR ALL ENTRIES IN lt_spfli
WHERE carrid = pa_carid
AND connid = lt_spfli-connid
我只是想,您希望从给定机场出发的每个航班转机...
注意,RANGE
结构在实际的 "compare value" 前面还有两个字段。所以直接选进去会导致很乱table。
可能的解决方案:
选择RANGE
如果您真的想使用这个临时 table,您可以看看我的回答 RANGE
的方法。完成此步骤后,您当前的代码段也将按照需要的方式工作。请确保它确实已被填充,否则所有内容都会被选中。
选择 FOR ALL ENTRIES
在使用此变体之前,您应该绝对确定您指定的数据对象已填充。否则它会导致与第一个解决方案相同的混乱。为此,您可以这样写:
* select connid
IF lt_spfli[] IS NOT INITIAL.
* select on SFLIGHT
ELSE.
* no result
ENDIF.
选择 JOIN
在这种情况下 "correct" 方法将是 JOIN
如:
SELECT t~*
FROM spfli AS i
JOIN sflight AS t
ON t~carrid = @pa_carid
AND t~connid = i~connid
INTO TABLE @DATA(li_conns)
WHERE i~airpfrom = @pa_airp.
您误解了“范围 Table”是什么。你填错了。
你的这部分代码证明了误解(稍加调试,你会立即看到错误的内容):
DATA: lt_spfli TYPE RANGE OF SPFLI.
SELECT CONNID FROM SPFLI INTO TABLE lt_spfli ...
“范围 Table”是一个内部 table,具有 4 个组件(SIGN、OPTION、LOW、HIGH),在 Open SQL 中用于在一个数据库上进行复杂的选择列(注意:它也可以用在多个 ABAP 语句中以测试 ABAP 变量的值)。
因此,使用您的 SQL 语句,您仅初始化范围 table 的第一个组件,而您应该将 CONNID
转移到第三个组件。
在“现代”中打开 SQL,你最好这样做:
SELECT 'I' as SIGN, 'EQ' as OPTION, CONNID as LOW FROM SPFLI INTO TABLE @lt_spfli ...
关于范围Table的更多信息,您可以参考这里的答案:What actually high and low means in a ranges table