2

我有一个 ABAP 类方法,比如 select_something。select_something 有一个导出参数,比如 et_result。et_result 是标准表类型,因为直到运行时才能确定 et_result 的类型。

该方法有时会给出一个简短的转储,说With ABAP/4 Open SQL array select, output table is too small at " select * into table et_result from (lv_tablename) where... "

错误分析:

......在这种特殊情况下,数据库表是 3806 字节宽,但内部表只有 70 字节宽。

我也试过“任何桌子”,错误是一样的。

4

4 回答 4

3

您可以返回数据引用。您的查询将不再失败,之后您可以将数据分配给正确键入的字段符号。

" 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 的观点,即应尽可能避免动态查询(以及相关的编程)。

于 2012-07-31T08:27:50.910 回答
2

你试图做的事情在很多层面上看起来都非常错误。除非有人用枪指着您的头并且门已锁紧,否则切勿使用 SELECT FROM(无论如何)。您将失去系统可能为您提供的各种静态错误检查。例如,编译器将不再能够告诉您“嘿,您正在读取的表是 3806 字节宽”。即使您使用常量,它也无法分辨。你会发现这很困难,会产生短暂的转储,尤其是在 unicode 和 NUC 系统之间切换时,很可能是在生产系统中。没有什么好玩的。

(实际上,在 SELECT 语句中动态表名有一些 - 非常非常非常少 - 很好的用途。我大约每两到三年需要一次,而且我编写了很多奇怪的东西。尽可能避免使用它们,即使以编写更多代码为代价。只是不值得稍后修复损坏的东西。)

然后,更改泛型形式参数类型不会对实际参数的类型做任何事情。如果您将 STANDARD TABLE OF mandt WITH DEFAULT KEY 传递给您的方法,则该表将包含 3 个字符的行。它将是一个标准表,因此,它也将是一个任意表,仅此而已。你可以在任何你喜欢的地方扭曲泛型类型,没有办法像你使用它们那样使用泛型类型来强制正确性。由调用者确保使用了所有正确的类型。那是一种糟糕的飞行方式。

于 2012-07-30T17:50:22.803 回答
0

完全同意 vwegert,但如果除了使用动态选择语句和动态类型参数之外,绝对没有其他方法(通常有)执行您的任务,请在运行时对表的类型和参数进行一些检查.

使用 CL_ABAP_TYPEDESCR 及其子类来执行此操作。

这样,您可以在运行时处理错误而无需程序转储,

但正如 vwegert 所说,这种动态的东西是纯粹的邪恶,并且肯定会在运行时的某个时候中断。添加必要的错误处理很可能比将代码重新设计为非动态 SQL 和类型化参数需要更多的工作和更难

于 2012-07-31T08:24:20.250 回答
0

首先,我同意 vwegert 的回应,如果可以的话尽量避免动态 sql 选择

也就是说,检查短转储。如果错误是异常类,您可以将 SELECT 语句包装在 try/catch 块中,并至少阻止它转储。

你也可以试试“ INTO CORRESPONDING FIELDS OF TABLE et_result”。如果 ET_RESULT 是动态的,您可能必须使用 RTTS 将其转换为正确的结构。可能会给你一些想法......

于 2012-07-31T04:15:12.893 回答