Просмотр Исходного

{toc:maxlevel=2}

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

В состав биллинга входит набор стандартных отчётов. Если у Вас возникла проблема с одним из них то:
# Возможно в отчёте уже есть нужные исправления. Скопируйте свежую версию отчёта к себе на биллинг из демонстрационной базы данных https://demo5.carbonsoft.ru/admin/reports/AdminCustomReports/
{info}
Для доступа к демо базе авторизуйтесь на [странице|https://www.carbonsoft.ru/products/carbon_billing/demo-access/?land=modern]
{info}
# Если в свежей версии отчёта также есть ошибка обратитесь к [нам|https://helpdesk.carbonsoft.ru/login.php]

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

{info}Мы используем *Firebird 2.5*, детальную информацию по языку СУБД Вы можете посмотреть по ссылкам:
* [Firebird 2.5 Language Reference Update|https://firebirdsql.org/refdocs/langrefupd25.html] - наиболее исчерпывающее оффициальное руководство на английском языке
* [Руководство по языку SQL СУБД Firebird 2.5|https://firebirdsql.org/file/documentation/reference_manuals/Firebird_Language_Reference_RUS.pdf] - то же самое на русском языке
* [Словарик по FireBird|http://firebirdsql.su/doku.php?id=o_sajte] - сайт посвященный Firebird на русском языке, поиском можно найти описание большинства функций с примерами
{info}

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

{code}
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
{code}
Отчет не выполнится, разберём почему.

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

h4. Ошибка в алиасах
{code:title=Текст ошибки}Column unknown\n- AV.ABONENT_ID\n- At line 8, column 51{code}
При соединении таблиц _abonents_ и _attribute_values_ мы дали им "алиасы", чтобы проще и короче писать наименования полей
* _abonents_ - *a*
* _attribute_values_ - *av_addr*

Но при указании условий объединения таблиц, мы используем неправильный алиас для _attribute_values_ - *av*
{code:title=Было}on a.id=av.abonent_id and av.attribute_id=3{code}
Чтобы исправить, замените исправьте алиас:
{code:title=Стало}on a.id=av_addr.abonent_id and av_addr.attribute_id=3 {code}

h4. Ошибка в имени поля
Так же ошибку вызовет поле *a.na{color:red}k{color}me* - в нем лишняя буква "k", правильно *a.name* - потому что так оно называется в таблице ABONENTS, из которой отчёт берёт данные.
{code:title=Было}
select
a.nakme || ';' ||
{code}
{code:title=Стало}
select
a.name || ';' ||
{code}

h3. Логическая - поля действительно не существует
{code:title=Текст ошибки}Column unknown\n- U.IP\n- At line 6, column 20'{code}
Исправив ошибку алиаса, мы получаем новую и тоже "Column unknown". Поле которое его вызвало - *u.ip*. Если посмотреть набор таблиц, которые мы объединяем, то таблицы учетных записей _users_ мы там не найдем. Для исправления присоедините эту таблицу:
{code:title=Было}
from
abonents a
join attribute_values av_addr
on a.id=av_addr.abonent_id
and av_addr.attribute_id=3
{code}
{code:title=Стало}
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
{code}

h2. Отчет завершился ошибкой "Token unknown"
{code:title=Текст ошибки}Token unknown - line 6, column 17{code}
Таблицу Users добавили, но опять ошибка в 6 строке. Проблему вызвало то, что после *t.name* пропущен операнд объединения строк *||* (или запятая, если строится для конструктора, а не для СОРМ). Исправим:
{code:title=Было}
t.name
uf_ip2string(u.ip)
{code}
{code:title=Стало}
t.name || ';' ||
uf_ip2string(u.ip)
{code}

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

!sql_error_none.png|border=0,width=300!

Если появляются записи "None", значит есть абоненты попадающие в выборку, но данные, которые мы пытаемся получить, не заполнены. В таком случае СУБД в ответ на запрос отвечает "null" или "none".
Для решения проблемы используйте конструкцю *coalesce*, задавая какое-то "стандартное" значаение, оно будет выводиться вместо None.
{code:title=Было}'Создан: ' || a.activate_date || ';' ||{code}
{code:title=Стало}'Создан: ' || coalesce(a.activate_date,'1970-01-01 00:00:01') || ';' ||{code}

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

Отчёт опять завершится ошибкой, но уже другой: "_arithmetic exception, numeric overflow, or string truncation_". Она говорит о том, что мы пытамся производить операции над данными [разных типов|https://firebirdsql.org/manual/migration-mssql-data-types.html], что в ряде случаев пройдет успешно и СУБД произведёт конверсию автоматический, но не всегда.
Чтобы решить проблему, все данные приведём к единому типу: текст. Преобразуем *a.activate_date* в строковый формат, чтобы СУБД могла правильно объединить его с остальным текстом:
Возьмём пример с датой выше и добавим преобразование в строку:
{code:title=Было}'Создан: ' || coalesce(a.activate_date,'1970-01-01 00:00:01') || ';' ||{code}
{code:title=Стало}'Создан: ' || coalesce(cast(a.activate_date as varchar(32)),'1970-01-01 00:00:01') || ';' ||{code}

h2. В выгрузке нет ни одной записи
!sql_error_empty.png|border=0,width=300!
Причин может быть две:
* По условиям запроса и правда нет данных
* При объединении таблиц, в одной из них не оказалось искомых записей

h3. По условиям запроса и правда нет данных
Попробуйте взять контрольного абонента, в конец условий добавить его ID:
{code}where
a.deleted=0
and a.id=12345{code}

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

h3. При объединении таблиц, в одной из них не оказалось искомых записей
Попробуйте заменить объединения через JOIN на LEFT JOIN (о разницы между ними Вы можете почитать в [справке по оператору в Википедии|https://ru.wikipedia.org/wiki/Join_(SQL)])
{code:title=Было}
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
{code}
{code:title=Стало}
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
{code}
{info}Если данных в таблицах много, LEFT JOIN может существенно замедлить выполнение отчета.{info}

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

Такая ошибка может возникнуть если в отчете допущена любая ошибка, и при этом в тексте отчета есть символ процента "%" или другие спецсимволы.
Ниже приведены несколько примеров как решить такую проблему.

h3. Параметры заполнения формы
Если Вы сделали отчет для выполнения в [конструкторе отчетов|CarbonBilling:Конструктор отчетов] и добавили в форму параметры для заполнения ("_Параметры полей формы_"), то их нужно убрать чтобы увидеть реальную ошибку отчета.

Чтобы найти проблему:
# Замените все _заполняемые_ параметры статическими, например: \\ \\
{code:title=Было}BILL_DATE between ':1-Начало|date$' and ':2-Конец|date$'{code}
{code:title=Стало}BILL_DATE between '2019-10-01' and '2019-10-31'{code} \\
# Выполните отчет и в выводе будет описана настоящая ошибка.

h3. Символ "%"

Если где-либо в отчёте Вы используете символ процента "%", его тоже необходимо убрать:
* Возможно Вы используете оператор "LIKE" чтобы найти подходящие строки, например:
{code:title=Было}when ABONENTS.NAME like '%Васильев%'{code}
Его можно заменить на оператор "CONTAINING" получив приблизительно тот же эффект
{code:title=Стало}when ABONENTS.NAME containing 'Васильев'{code}
В любом случае, исправив основную ошибку отчета, форму LIKE можно будет вернуть.
* Еще возможный вариант - Вы вывводите символ процента чтобы обозначить что в столбце отображаются именно проценты, например:
{code:title=Было}select '3% суммы всех платежей: ' sum(OP_SUMMA)/100*3 from FINANCE_OPERATIONS where OP_TYPE=2{code}
Просто уберите из отчета символ процента и в данном отчете увидите ошибку "arithmetic exception...":
{code:title=Стало}select '3 процента суммы всех платежей: ' sum(OP_SUMMA)/100*3 from FINANCE_OPERATIONS where OP_TYPE=2{code}
После исправления основной ошибки отчета, символ процента можно будет вернуть.

h2. При выполнении отчета возникла ошибка "Произошла ошибка по адресу http://***/admin/reports/AdminCustomReports/250001/executesql/
В описании ошибки будет запись следующего вида:
{code}DjangoUnicodeDecodeError: 'utf8' codec can't decode byte 0xd0 in position 30: unexpected end of data. You passed in '\xd0\x92......' (<type 'str'>) {code}
Причиной данной ошибки является превышение количества символов при наименовании столбца кирилицей в итоговом отчете. Поле может иметь название не более 18 символов.
Пример:
{code:title=Было}s_time as "Время начала звонка"{code}
Для решения проблемы, сократите название, либо укажите наименование латиницей.
Несколько вариантов, как можно исправить наименование поля:
{code:title=Стало, вариант 1}
s_time as "Вр.начала звонка"
{code}
{code:title=Стало, вариант 2}
s_time as "Начало звонка"
{code}
{code:title=Стало, вариант 3}
s_time as "Vremia nachala zvonka"
{code}

h2. Я не могу найти ошибку. Что делать?
+Локализуйте проблему+. Максимально упростите запрос и постепенно добавляйте объединения таблиц, или наоборот - постепенно удаляйте поля из исходного запроса.
Например
# Упростите начальный запрос до такого:
{code}
select
a.nakme
from
abonents a
{code}
Отчет завершится с ошибкой "_Column unknown_" - еще раз прочитав запроса вероятно станет понятно, что скорей всего поля "nakme" не существует и в нем лишний символ.
# Исправив ошибку в поле a.name, добавьте еще +одно поле+ из исходного запроса:
{code}
select
a.name || ';' ||
'Создан: ' || a.activate_date || ';' ||
from
abonents a
{code}
Отчет завершится ошибкой "Token unknown", так как последнее поле завершается [оператором объединения строк|https://firebirdsql.org/refdocs/langrefupd15-concat.html].
# Приведите отчет к рабочему виду:
{code}
select
a.name || ';' ||
'Создан: ' || a.activate_date
from
abonents a
{code}
В выводе будет множество полей "None". Причина - заведено множество еще не активированных абонентов + в вывод попали папки, когда хотели получить только абонентов. Исправьте:
{code}
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
{code}

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