Отладка отчетов

Skip to end of metadata
Go to start of metadata

Почему вообще могут возникнуть ошибки?

Отчеты из статей ориентированы на стандартный набор реквизитов и их параметры. Чем отчет больше, тем выше вероятность допустить ошибку в какой-нибудь мелочи. Работая над большими отчетами, вероятней всего, придется потратить какое-то время на их отладку.

Мы писпользуем Firebird 2.1, детальную информацию по языку СУБД Вы можете посмотреть по ссылкам:
  • Firebird 2.1 Language Reference Update - наиболее исчерпывающее оффициальное руководство на английском языке
  • Руководство по языкуSQL СУБД Firebird 2.5 - то же самое на русском языке для версии СУБД 2.5, от 2.1 в основном отличие в добавлении новых функций и процедур
  • Словарик по FireBird - сайт посвященный Firebird на русском языке, поиском можно найти описание большинства функций с примерами

Пример отчета

Допустим, проблема с отчетом выгрузки карточек абонентов

select
    a.nakme || ';' ||
    'Создан: ' || a.activate_date || ';' ||
    h.city || ', ' || h.street || ', ' || h.s_number || ';' ||
    t.name
    uf_ip2string(u.ip)
from 
    abonents a 
    join attribute_values av_addr on a.id=av_addr.abonent_id and av_addr.attribute_id=3 
        join homes h on av_addr.attribute_value=h.id 
    join tarif t on a.tarif_id=t.id 
where 
    a.deleted=0 

Отчет не выполнится, разберём почему.

Отчет завершился ошибкой "Column unknown"

Ошибка "Column unknown" говорит о том, что в структуре отчета Вы пытаетесь получить данные из несуществующей колонки.
Причин может быть несколько.

Орфографическая ошибка

Ошибка в алиасах

Текст ошибки
Column unknown\n- AV.ABONENT_ID\n- At line 8, column 51

При соединении таблиц abonents и attribute_values мы дали им "алиасы", чтобы проще и короче писать наименования полей

  • abonents - a
  • attribute_values - av_addr

Но при указании условий объединения таблиц, мы используем неправильный алиас для attribute_values - av

Было
on a.id=av.abonent_id and av.attribute_id=3

Чтобы исправить, замените исправьте алиас:

Стало
on a.id=av_addr.abonent_id and av_addr.attribute_id=3 

Ошибка в имени поля

Так же ошибку вызовет поле a.nakme - в нем лишняя буква "k", правильно a.name

Было
select
    a.nakme || ';' ||
Стало
select
    a.name || ';' ||

Логическая - поля действительно не существует

Текст ошибки
Column unknown\n- U.IP\n- At line 6, column 20'

Исправив ошибку алиаса, мы получаем новую и тоже "Column unknown". Поле которое его вызвало - u.ip. Если посмотреть набор таблиц, которые мы объединяем, то таблицы учтены записей users мы там не найдем. Для исправления присоедините эту таблицу:

Было
from 
    abonents a 
    join attribute_values av_addr on a.id=av_addr.abonent_id and av_addr.attribute_id=3 
Стало
from 
    abonents a 
    join users u on a.id=u.abonent_id
    join attribute_values av_addr on a.id=av_addr.abonent_id and av_addr.attribute_id=3 

Отчет завершился ошибкой "Token unknown"

Текст ошибки
Token unknown - line 6, column 17

Таблицу Users добавили, но опять ошибка в 6 строке. Проблему вызвало то, что после t.name пропущен операнд объединения строк || (или запятая, если строится для конструктора, а не для СОРМ). Исправим:

Было
    t.name
    uf_ip2string(u.ip)
Стало
    t.name || ';' ||
    uf_ip2string(u.ip)

Отчет выполнился, но записи только "None"

Если появляются записи "None", значит есть абоненты попадающие в выборку, но в каких-то полях нет значения - null, none.
Для решения проблемы используйте конструкцю coalesce, задавая какое-то значение по-умолчанию, но предварительно преобразуем a.activate_date в строковый формат:

Было
'Создан: ' || a.activate_date || ';' ||
Стало
'Создан: ' || coalesce(cast(a.activate_date as varchar(32)),'1970-01-01 00:00:01') || ';' ||

Отчет завершился ошибкой "arithmetic exception, numeric overflow, or string truncation"

Ошибка "arithmetic exception, numeric overflow, or string truncation" говорит о том, что мы пытамся производить операции над данными разных типов, что в ряде случаев пройдет успешно и СУБД произведёт конверсию автоматический, но не всегда.
Если взять пример где все записи были "None" и убрать оттуда предварительную конверсию даты в строку, вот так:

'Создан: ' || coalesce(a.activate_date,'1970-01-01 00:00:01') || ';' ||

То мы получим эту ошибку.

В выгрузке нет ни одной записи


Причин может быть две:

  • По условиям запроса и правда нет данных
  • При объединении таблиц, в одной из них не оказалось искомых записей

По условиям запроса и правда нет данных

Попробуйте взять контрольного абонента, в конец условий добавить его ID:

where
    a.deleted=0
    and a.id=12345

И постепенно убирать дополнительные условия.

При объединении таблиц, в одной из них не оказалось искомых записей

Попробуйте заменить объединения через JOIN на LEFT JOIN (о разницы между ними Вы можете почитать в справке по оператору в Википедии)

Было
    join attribute_values av_addr on a.id=av_addr.abonent_id and av_addr.attribute_id=3 
        join homes h on av_addr.attribute_value=h.id 
Стало
    left join attribute_values av_addr on a.id=av_addr.abonent_id and av_addr.attribute_id=3 
        left join homes h on av_addr.attribute_value=h.id 
Если данных в таблицах много, LEFT JOIN может существенно замедлить выполнение отчета.

При выполнении отчета ошибка "not enough arguments for format string"

Такая ошибка может возникнуть если Вы сделали отчет для выполнения в конструкторе отчетов и добавили в форму параметры для заполнения ("Параметры полей формы"), при этом где-то в отчете допущена ошибка - одна из выше описанных.

Чтобы найти проблему:

  1. Замените все заполняемые параметры статическими, например:

    Было
    BILL_DATE between ':1-Начало|date$' and ':2-Конец|date$'
    Стало
    BILL_DATE between '2019-10-01' and '2019-10-31'


  2. Выполните отчет и в выводе будет описана настоящая ошибка.

Я не могу найти ошибку. Что делать?

Локализуйте проблему. Максимально упростите запрос и постепенно добавляйте объединения таблиц, или наоборот - постепенно удаляйте поля из исходного запроса.
Например

  1. Упростите начальный запрос до такого:
    select
        a.nakme
    from 
        abonents a 
    

    Отчет завершится с ошибкой "Column unknown" - еще раз прочитав запроса вероятно станет понятно, что скорей всего поля "nakme" не существует и в нем лишний символ.

  2. Исправив ошибку в поле a.name, добавьте еще одно поле из исходного запроса:
    select
        a.name || ';' ||
        'Создан: ' || a.activate_date || ';' ||
    from 
        abonents a 
    

    Отчет завершится ошибкой "Token unknown", так как последнее поле завершается оператором объединения строк.

  3. Приведите отчет к рабочему виду:
    select
        a.name || ';' ||
        'Создан: ' || a.activate_date
    from 
        abonents a 
    

    В выводе будет множество полей "None". Причина - заведено множество еще не активированных абонентов + в вывод попали папки, когда хотели получить только абонентов. Исправьте:

    select
        a.name || ';' ||
        'Создан: ' || coalesce(cast(a.activate_date as varchar(32)),'1970-01-01 00:00:01')
    from 
        abonents a 
    where
        a.is_folder=0
    

И так далее, пока не восстановите полную структуру начального отчета.

Введите метки, чтобы добавить к этой странице:
Please wait 
Ищите метку? просто начните печатать.