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

Skip to end of metadata
Go to start of metadata

Стандартные отчёты

В состав биллинга входит набор стандартных отчётов. Если у Вас возникла проблема с одним из них то:

  1. Возможно в отчёте уже есть нужные исправления. Скопируйте свежую версию отчёта к себе на биллинг из демонстрационной базы данных https://demo5.carbonsoft.ru/admin/reports/AdminCustomReports/
    Для доступа к демо базе авторизуйтесь на странице
  2. Если в свежей версии отчёта также есть ошибка обратитесь к нам

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

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

Мы используем Firebird 2.5, детальную информацию по языку СУБД Вы можете посмотреть по ссылкам:

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

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

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.abonent_id and av.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 - потому что так оно называется в таблице ABONENTS, из которой отчёт берёт данные.

Было
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, задавая какое-то "стандартное" значаение, оно будет выводиться вместо None.

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

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

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

Было
'Создан: ' || coalesce(a.activate_date,'1970-01-01 00:00:01') || ';' ||
Стало
'Создан: ' || coalesce(cast(a.activate_date as varchar(32)),'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. Выполните отчет и в выводе будет описана настоящая ошибка.

Символ "%"

Если где-либо в отчёте Вы используете символ процента "%", его тоже необходимо убрать:

  • Возможно Вы используете оператор "LIKE" чтобы найти подходящие строки, например:
    Было
    when ABONENTS.NAME like '%Васильев%'

    Его можно заменить на оператор "CONTAINING" получив приблизительно тот же эффект

    Стало
    when ABONENTS.NAME containing 'Васильев'

    В любом случае, исправив основную ошибку отчета, форму LIKE можно будет вернуть.

  • Еще возможный вариант - Вы вывводите символ процента чтобы обозначить что в столбце отображаются именно проценты, например:
    Было
    select '3% суммы всех платежей: ' sum(OP_SUMMA)/100*3 from FINANCE_OPERATIONS where OP_TYPE=2

    Просто уберите из отчета символ процента и в данном отчете увидите ошибку "arithmetic exception...":

    Стало
    select '3 процента суммы всех платежей: ' sum(OP_SUMMA)/100*3 from FINANCE_OPERATIONS where OP_TYPE=2

    После исправления основной ошибки отчета, символ процента можно будет вернуть.

При выполнении отчета возникла ошибка "Произошла ошибка по адресу http://***/admin/reports/AdminCustomReports/250001/executesql/

В описании ошибки будет запись следующего вида:

DjangoUnicodeDecodeError: 'utf8' codec can't decode byte 0xd0 in position 30: unexpected end of data. You passed in '\xd0\x92......' (<type 'str'>) 

Причиной данной ошибки является превышение количества символов при наименовании столбца кирилицей в итоговом отчете. Поле может иметь название не более 18 символов.
Пример:

Было
s_time as "Время начала звонка"

Для решения проблемы, сократите название, либо укажите наименование латиницей.
Несколько вариантов, как можно исправить наименование поля:

Стало, вариант 1
s_time as "Вр.начала звонка"
Стало, вариант 2
s_time as "Начало звонка"
Стало, вариант 3
s_time as "Vremia nachala zvonka"

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

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

  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 
Ищите метку? просто начните печатать.