Как предотвратить разрыв строки в длинном текстовом значении, возвращаемом из хранимой процедуры Informix - PullRequest
1 голос
/ 26 апреля 2019

Я пишу хранимую процедуру, которая имитирует Informix UNLOAD, так что я получаю вывод в текстовый файл с разделителями для передачи в другую систему. Моя процедура работает, как и ожидалось, но когда я перенаправляю вывод в текстовый файл в моем сценарии оболочки, строки прерываются после 66 символов. Мне нужно, чтобы каждая запись была отдельной строкой без разрывов строк в записи.

Текстовая строка, которую он возвращает для каждой записи, может содержать до 350 символов. Есть ли параметр Informix, который вызывает это? Что-то в моем сценарии оболочки?

Вся процедура включена ниже. Я также добавил код, который показывает, как я вызываю этот SP из сценария оболочки.

Мы используем Solaris 10 и Informix IDS 11.70.

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

# Real script receives these as args or calculates using today's date
begin_date="2019-04-26 00:00:00"
end_date="2019-04-26 23:59:59"
dbname="mydatabase"
STORED_PROCEDURE="sp_unload_mytable"
OUTFILE="return.dat"

rm -f $OUTFILE
echo "execute procedure ${STORED_PROCEDURE}('${begin_date}','${end_date}') " | dbaccess $dbname \
| sed 's,(expression),,' | sed 's/,$//' | sed -e '/^$/d' | sed 's/^[ ]*//' > $OUTFILE
create procedure sp_unload_mytable(start_date datetime year to second, end_date datetime year to second)
   returning lvarchar(500);

   DEFINE p_rep_serial      integer;
   DEFINE p_post_flag       integer;
   DEFINE p_recording_date  varchar(8);
   DEFINE p_lastname        varchar(35);
   DEFINE p_firstname       varchar(20);
   DEFINE p_middlename      varchar(20);
   DEFINE p_generation      varchar(4);
   DEFINE p_role        varchar(8);
   DEFINE p_corporperson    varchar(1);
   DEFINE p_party_type      varchar(1);
   DEFINE p_b           varchar(5);
   DEFINE p_p           varchar(4);
   DEFINE p_item_number     varchar(4);
   DEFINE p_i_code          varchar(3);
   DEFINE p_i_desc          varchar(10);
   DEFINE p_par_id      varchar(12);
   DEFINE p_ref_b               varchar(5);
   DEFINE p_ref_p           varchar(4);
   DEFINE p_remark_1        varchar(20);
   DEFINE p_remark_2        varchar(20);
   DEFINE p_i_id            varchar(10);
   DEFINE p_ret_code        varchar(12);
   DEFINE p_nbr_of_attempts varchar(12);
   DEFINE p_insert_timestamp    datetime year to second;
   DEFINE p_edit_flag       varchar(12);
   DEFINE p_document_id     varchar(12);
   DEFINE p_version     varchar(6);
   DEFINE p_attempts        varchar(6);
   DEFINE p_return      lvarchar(500);

   FOREACH SELECT rep_serial, post_flag, nvl(recording_date, ""),
        nvl(lastname, ""), nvl(firstname, ""), nvl(middlename, ""), 
        nvl(trim(generation), ""), nvl(trim(role), ""), 
        nvl(trim(corporperson), ""), nvl(trim(party_type), ""), 
                  nvl(trim(b), ""), nvl(trim(p), ""), nvl(trim(item_number), ""), 
                  nvl(trim(i_code), ""), nvl(trim(i_desc), ""), 
                  nvl(par_id, ""), nvl(trim(ref_b), ""), 
                  nvl(trim(ref_p), ""), nvl(remark_1, ""), nvl(remark_2, ""), 
                  nvl(i_id, ""), nvl(ret_code, ""), nvl(nbr_of_attempts, ""), 
                  nvl(insert_timestamp, ""), nvl(edit_flag, ""), nvl(document_id, ""), 
                  nvl(version, ""), nvl(attempts, "")
        INTO p_rep_serial, p_post_flag, p_recording_date, p_lastname, p_firstname, 
             p_middlename, p_generation, p_role, p_corporperson, p_party_type, 
             p_b, p_p, p_item_number, p_i_code, p_i_desc, 
             p_par_id, p_ref_b, p_ref_p, p_remark_1, 
             p_remark_2, p_i_id, p_ret_code, p_nbr_of_attempts, 
             p_insert_timestamp, p_edit_flag, p_document_id, p_version, p_attempts
        from mytable
        where insert_timestamp between start_date and end_date

        LET p_return = p_rep_serial || "|" || p_post_flag || "|" || p_recording_date || "|" || p_lastname || "|" || p_firstname || "|" || p_middlename || "|" || p_generation || "|" || p_role || "|" || p_corporperson || "|" || p_party_type || "|" || p_b || "|" || p_p || "|" || p_item_number || "|" || p_i_code || "|" || p_i_desc || "|" || p_par_id || "|" || p_ref_b || "|" || p_ref_p || "|" || p_remark_1 || "|" || p_remark_2 || "|" || p_i_id || "|" || p_ret_code || "|" || p_nbr_of_attempts || "|" || p_insert_timestamp || "|" || p_edit_flag || "|" || p_document_id || "|" || p_version || "|" || p_attempts;

        RETURN p_return WITH RESUME;

   END FOREACH;

end procedure;

1 Ответ

1 голос
/ 27 апреля 2019

Проблема связана с DB-Access.

Если вы использовали достаточно свежую версию Informix (12.10.xC12 или 14.10.xC1 или новее в каждом из этих семейств версий), вы можете использоватьпеременная окружения DBACCESS_COLUMNS для установки эффективной ширины «экрана» (вывод).Однако если в самих данных содержатся новые строки, они будут отражены в выходных данных.Помимо принудительного вывода вывода в JSON (что не особенно просто, но вы можете посмотреть genBSON, если вам интересно), я не знаю способа удалить переводы строки или заменитьс \n или подобным, за исключением последующей обработки вывода DB-Access.

Поскольку ваша версия Informix (11.70) слишком устарела для поддержки DBACCESS_COLUMNS, я не уверен, что естьдействительно хорошая альтернатива.

В крайнем случае, вы могли бы использовать мою программу SQLCMD (не имеет отношения к одноименному постороннему лицу Microsoft с тем же именем).Чтобы получить его там, вам нужно присоединиться к IIUG (Международная группа пользователей Informix), которая бесплатна и не требует слишком большого количества электронных писем (пару раз в месяц, если вы не подпишетесь ни на один из списков рассылки).Преимущество SQLCMD перед DB-Access состоит в том, что он автоматически выводит «настолько широко, насколько необходимо», но у него нет режима вывода для «не включать прямые строки», кроме как через вывод в стиле JSON (который, как я вижу,необходимо исправить ошибку в v91.03, которая является более новой, чем на веб-сайте IIUG, - на данный момент это не достаточно полезная опция).Я подумаю над тем, чтобы добавить опцию «Выход из выхода в стиле C» (или, может быть, это будет просто стиль JSON, так как в любом случае мне нужно лучше обрабатывать JSON - TBD).SQLCMD должен компилировать нормально практически с любой версией Informix (ESQL / C), на которую вы можете положиться.

...