Ошибка SELECT FROM (lv_tablename): выходная таблица слишком мала

У меня есть метод класса ABAP, скажем, select_something. select_something имеет параметр экспорта, например et_result. et_result имеет тип стандартной таблицы, потому что тип et_result не может быть определен до времени выполнения.

Метод иногда дает короткий дамп с сообщением: При выборе массива ABAP / 4 Open SQL, выходная таблица слишком мала в строке «выберите * в таблицу et_result from (lv_tablename), где ... "

Анализ ошибок:

...... в данном конкретном случае ширина таблицы базы данных составляет 3806 байт, а ширина внутренней таблицы - всего 70 байт.

Я тоже пробовал "любую таблицу", и ошибка та же.


person Dustin Sun    schedule 30.07.2012    source источник


Ответы (4)


Вы можете вернуть ссылку на данные. Ваш запрос больше не будет терпеть неудачу, и вы можете впоследствии назначить данные правильно набранному символу поля.

" 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 в том, что динамических запросов (и программирования в этом отношении) следует по возможности избегать.

person René    schedule 31.07.2012

То, что вы пытаетесь сделать, на многих уровнях выглядит ужасно неправильным. НИКОГДА не используйте SELECT FROM (что угодно), если кто-то не направит пистолет вам в голову и дверь будет плотно заперта. Вы потеряете все виды статических ошибок, проверяющих, что система может вам предоставить. Например, компилятор больше не сможет сказать вам: «Эй, эта таблица, из которой вы читаете, имеет ширину 3806 байт». Он просто не может сказать, даже если вы используете константы. Вы обнаружите это на собственном горьком опыте, создавая короткие дампы, особенно при переключении между системами Unicode и NUC, вполне вероятно, что некоторые из них в производственных системах. Не весело.

(На самом деле есть несколько - очень-очень-очень мало - хороших применений для имен динамических таблиц в операторе SELECT. Они мне нужны примерно раз в два-три года, и я кодирую довольно много странных вещей. Просто избегайте их везде, где можете, даже ценой написания большего количества кода. Это просто не стоит проблем с исправлением сломанных вещей позже.)

Затем изменение общего формального типа параметра ничего не меняет с типом фактического параметра. Если вы передадите СТАНДАРТНУЮ ТАБЛИЦУ mandt С КЛЮЧОМ ПО УМОЛЧАНИЮ в свой метод, эта таблица будет содержать строки из 3 символов. Это будет СТАНДАРТНАЯ ТАБЛИЦА, и как таковая, это также будет ЛЮБАЯ ТАБЛИЦА, вот и все. Вы можете крутить универсальные типы где угодно, нет способа обеспечить правильность, используя общие типы так, как вы их используете. Вызывающий должен убедиться, что используются все правильные типы. Это плохой способ летать.

person vwegert    schedule 30.07.2012
comment
Как правильно выбрать * из таблицы zxx, где field1 = 'something'? - person Dustin Sun; 30.07.2012

Во-первых, я согласен с ответом vwegert, старайтесь избегать динамического выбора sql, если можете

Тем не менее, проверьте короткий дамп. Если ошибка относится к классу исключения, вы можете заключить оператор SELECT в блок try / catch и, по крайней мере, предотвратить его сброс.

Вы также можете попробовать "INTO CORRESPONDING FIELDS OF TABLE et_result". Если ET_RESULT является динамическим, вам, возможно, придется преобразовать его в правильную структуру с помощью RTTS. Это может дать вам некоторые идеи ...

person Jorg    schedule 31.07.2012

Не могу больше согласиться с vwegert, но если нет абсолютно другого способа (и обычно есть) для выполнения вашей задачи, кроме использования динамических операторов выбора и динамически типизированных параметров, выполните некоторые проверки типа таблицы и параметра во время выполнения .

Для этого используйте CL_ABAP_TYPEDESCR и его подклассы.

Таким образом, вы можете обрабатывать ошибки во время выполнения без сброса вашей программы,

Но, как сказал Вегерт, этот динамический материал - чистое зло и наверняка сломается в какой-то момент во время выполнения. Добавление необходимой обработки ошибок, скорее всего, будет намного сложнее и сложнее, чем перепроектирование вашего кода без динамического SQL и типизированных параметров.

person Hans Hohenfeld    schedule 31.07.2012