我有一个ABAP类方法,比如select_something。select_something有一个导出参数,比如et_result。et_result是标准表类型,因为在运行时之前无法确定et_resull的类型。
该方法有时会给出一个简短的转储,说使用ABAP/4 Open SQL数组select,输出表太小在"select*into table et_result from(lv_tablename)where…"
错误分析:
。。。。。。在这种特殊情况下,数据库表的宽度为3806字节,但内部表的宽度仅为70字节
我也试过"任意表",但错误是一样的。
您可以返回一个数据引用。查询将不再失败,之后可以将数据分配给正确键入的字段符号。
" Definition
class-methods select_all
importing
!tabname type string
returning
value(results) type ref to data.
...
...
" Implementation
method select_all.
data dref type ref to data.
create data dref type standard table of (tabname).
field-symbols <tab> type any table.
assign dref->* to <tab>.
select * from (tabname) into table <tab>.
get reference of <tab> into results.
endmethod.
此外,我同意@vwegert的观点,即尽可能避免动态查询(以及编程)。
您试图做的事情在很多层面上看起来都是错误的。除非有人用枪指着你的头,而且门锁得很紧,否则永远不要使用SELECT FROM(任何)。您将失去系统可能为您提供的各种静态错误检查。例如,编译器将无法再告诉你"嘿,你正在读取的表有3806字节宽。"即使你使用常量,它也无法告诉你。你会发现这很难,产生短转储,尤其是在unicode和NUC系统之间切换时,很可能是在生产系统中。没有乐趣。
(事实上,SELECT语句中动态表名有一些非常非常少的好用途。我大约每两到三年需要一次,而且我编写了很多奇怪的东西。只要尽可能避免它们,即使要付出写更多代码的代价。以后修复坏东西的麻烦是不值得的。)
然后,更改泛型形式参数类型对实际的参数类型没有任何作用。如果将STANRDARD TABLE OF mandt WITH DEFAULT KEY传递给方法,那么该表将有3行字符。它将是一个STANDARD TABLE,因此,它也将是ANY TABLE,仅此而已。你可以在任何你喜欢的地方扭曲泛型类型,没有办法像使用泛型类型那样强制执行正确性。由调用者来确保使用了所有正确的类型。那是一种糟糕的飞行方式。
首先,我同意vwegert的回应,如果可以,尽量避免动态sql选择
也就是说,检查短转储。如果错误是一个异常类,则可以将SELECT语句包装在try/catch块中,并至少阻止其转储。
您也可以尝试"INTO CORRESPONDING FIELDS OF TABLE et_result
"。如果ET_RESULT是动态的,则可能需要使用RTTS将其强制转换为正确的结构。这可能会给你一些想法。。。
非常同意vwegert,但如果除了使用动态选择语句和动态类型参数之外,没有其他方法(通常也没有)执行任务,请在运行时检查表的类型和参数。
使用CL_ABAP_TYPEDESCR及其子类来执行此操作。
这样,您就可以在运行时处理错误,而无需程序转储,
但正如vwegert所说,这种动态的东西纯粹是邪恶的,并且肯定会在运行时的某个时刻崩溃。添加必要的错误处理很可能比将代码重新设计为非动态SQL和类型化参数要多得多,也要困难得多