Pull to refresh

Comments 20

Извините

Там 26 строк. Перепечатать руками в табличку быстрее.

Для пяти стран за десять лет и не допустив ни одной ошибки? Ну-ну )

И Вы действительно думаете, что я потратил на эту функцию больше 5 минут?

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

5 стран это 100 строчек. Раз в год. Вбивается силами любой девочки.

Экран кода не пишется за 5 минут. Вероятно даже за час не пишется. Опять же тесты, обработка ошибок, развернуть куда-то, подумать как запускать и все такое. День работы точно. За 10 лет не окупится.

Вбивается силами любой девочки.

Особенно когда такая таблица переносимая и заполняется только через GIT.

День работы точно.

Мои соболезнования. Я столь простые функции из одного(!) SQL запроса действительно пишу за 5 минут.

Дело не в этом, а в примере, как читать из файла и парсить, и прочее.

Вот этот календарь, что по ссылке -- это первый шаг.

В странах бывают региональные праздники. Бывают праздники, когда день только укорачивается. Для разных бизнес-процессов бывает "если попадает на праздник, переносить на после, но если попадёт на следующий месяц, то перенести до праздника". Бывает, что вашей организации нужны данные "закрытие месяца" кровь из носу, а в Японии какой праздник, хотя по факту люди сидят где-то в Европе, и т.д., и т.п.

Грамотная поддержка календаря -- нетривиальная, но вполне решаемая задача задача.

А ещё бывает так, что правительство выделяет N дней в году на праздники, но какие из них M (M < N) дней будет выходными для сотрудников решает каждая компания сама. N и M регулируется государство на каждый год отдельно.

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

Работает исключительно в случаях, когда он нужен в справочных целях. Впрочем, подбор подтверждающих документов можно спихнуть на ОТиЗ и юристов. А сам календарь после первого же парсинга сохранить в служебной таблице - ну право слово, глупо же каждый раз лезть к чужому дяде и потом парсить его ответ.

Работает исключительно в случаях, когда он нужен в справочных целях.

Достаточно подбить итоги рабочих часов и выходных дней за год и по кварталам, после чего свериться с нормативкой.

А сам календарь после первого же парсинга сохранить в служебной таблице

А я написал иначе?

"Ну а уж из этой функции можно его сохранить в табличку и спокойно использовать до следующего Нового Года."

Ну и Вы, хоть и не первый, но тоже пропустили цель статьи: "Цель статьи - показать возможности COPY ... FROM PROGRAM и простейшие приемы парсинга XML в PostgreSQL."

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

Именно ради этих переносов и загружается производственный календарь. Что и позволяет процесс автоматизировать.

Вот раз в год один человек и фиксирует изменения производственного календаря. После чего миллионы могут этим уже автоматизировано воспользоваться.

В принципе неплохой пример как вытянуть данные и распарсить xml. Мне, как вообще не работающему с постгрессом было интересно. Правда резануло глаз - holYday это там в таком виде приходит? Еще попутно вопрос - надо по работе переписать кучу серверного кода с оракла на постгрес. Попробовал - это ужас. Никакой отладки или пошагового выполнения. Ошибку пишет только после запуска если дошло до неправильной строки - да и тут какую-то странную ссылку дает - типа ошибка в строке 3452 а такой строки нет. Собственно вопрос - есть какая-то среда разработки для постгресса с нормальной отладкой чтобы функцию написать не из одного селекта а со сложной логикой на несколько сотен строк? Ну и по календарю - почти в каждой области РФ он свой со своими праздниками. Всероссийские конечно тоже входят, но несколько региональных добавляется.

резануло глаз - holYday это там в таком виде приходит?

Нет. Это я в одном месте описку допустил.

Ошибку пишет только после запуска если дошло до неправильной строки

А в Oracle что-ли кто-то телепатически ошибки находит до запуска? Типа "вангую Вам дублирование ключей с такими-то значениями в строке такой-то"? Что-то не верится.

есть какая-то среда разработки для постгресса с нормальной отладкой

А тут надо понимать, что есть SQL диалект PostgreSQL, на котором, кстати можно писать и фукнции (LANGUAGE SQL), а есть еще целый ворох процедурных языков (plperlu, plpythonu, plrust, plr и т.п.). И если для SQL мне вполне хватает средств DBEaver, то уже как только начинаются DO блоки даже на plpgsql - у него конкретно сносит крышу. Собственно говоря, отладчик я знаю только для plpgsql в составе pgAdmin. Но сам пользуюсь им редко, так код процедур и так всегда в BEGIN ... EXCEPTION ... END, и в журнал пишется вообще все, что только можно получить через GET STACKED DIAGNOSTICS.

А в Oracle что-ли кто-то телепатически ошибки находит до запуска? Типа "вангую Вам дублирование ключей с такими-то значениями в строке такой-то"? Что-то не верится.

Это уже ошибка в данных, само собой такое предсказать невозможно. Я про другое. Попробовал перевести одну функцию с большим запросом внутри с оракла на пострес. Сконвертировал утилитой, само собой ничего сразу не скомпилировалось, в итоге почти все пришлось подправить руками. Суть в том, что в запросе были поля из таблицы, к которым не добавлен алиас таблицы. В самой функции тоже были поля с такими же наименованиями в блоке declare. Все нормально скомпилировалось. Но при запуске начало выдавать что поле дублируется, нужно добавить алиас. Номер строки при этом какой-то странный - ни внутри функции ни внутри селекта такой нет. Приходилось каждый раз просматривать, пытаться догадаться где же это произошло, менять, компилировать, заново запускать и смотреть пропало или нет. Оракл сругался бы на этапе компиляции указав на конкретную строку. В оракле, допустим, вы поменяли состав входных параметров функции которая вызывается в других функциях/процедурах/триггерах. Сразу после перекомпиляции все эти объекты станут инвалидными и будет видно в какой строке код теперь инвалидный. В постгрессе, как я понял, пока не вызовешь функцию и не поймешь что она не может выполниться впринципе.

В постгрессе, как я понял, пока не вызовешь функцию и не поймешь что она не может выполниться впринципе.

для этого тоже есть расширение plpgsql_check

Все нормально скомпилировалось.

Оракл сругался бы на этапе компиляции указав на конкретную строку.

С точки зрения PostgreSQL, процедуры и функции на любом языке, кроме SQL (LANGUAGE SQL) - это лишь строки, которые следует передать при их вызове соответствующему интерпретатору. Остальное - уже его проблемы.

Подозревая, что речь идет все же о plpgsql (PL/pgSQL), остановимся на его поведении. Он транслирует процедуру или функцию во внутреннее бинарное представление при первом ее запуске. При этом транслируются только конструкции языка PL/pgSQL, но не SQL предложения используемые в нем. SQL предложения транслируются SPI_prepare только при первом выполнении и результат кешируется для дальнейшего использования. Поэтому полная "компиляция" всего текста процедуры может вообще не произойти никогда, если какие-то SQL предложения еще ни разу не вызывались по логике ветвлений.

Отсюда, если Вы хотите произвести полную проверку синтаксиса процедуры или функции на PL/pgSQL, следует воспользоваться соответствующим расширением plpgsql_check. Сам интерпретатор PL/pgSQL для этой цели мало пригоден.

В оракле, допустим, вы поменяли состав входных параметров функции которая вызывается в других функциях/процедурах/триггерах.

А тут поведение PostgreSQL тоже радикально отличается. Он вообще не позволяет изменять состав входных параметров функции. Если у Вас была функция you_function(integer) и Вы создадите (CREATE OR REPLACE) функцию you_function(smallint), то это будет новая функция с тем же именем, но применяемая для типа параметра smallint. А старая останется для типа параметра integer.

Наглядно:

CREATE OR REPLACE FUNCTION you_function(x integer)
RETURNS integer AS $function$
<<func>>
BEGIN
RETURN x*2;
END; $function$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION you_function(x smallint)
RETURNS integer AS $function$
<<func>>
BEGIN
RETURN x/2;
END; $function$ LANGUAGE plpgsql;

SELECT you_function(10) AS I, you_function(10::smallint) AS S;

i,s
20,5

В постгрессе, как я понял, пока не вызовешь функцию и не поймешь что она не может выполниться впринципе.

Идеология поддержки неограниченного множества процедурных языков приводит именно к этому. Для самой СУБД интерпретаторы процедурных языков - черный ящик. И каждый из них может поступать по своему. Например, PL/pgSQL - интерпретатор, а вот PL/Rust - компилирует процедуры и функции в машинный код при первом запуске.

Большое спасибо за ответы и подсказки, я действительно имел ввиду pl/pgsql. Просто в оракле особого выбора нет, думал здесь так же принято - в основном на нем писать, остальное только прям если прижмет. Пока пробовал работать только в dbeaver. Буду пробовать/экспериментировать.

К сожалению, только для plpgsql. С теми же plperlu, plr, plpythonu - кувыркайся как знаешь (

Человек написал отличный туториал по работе с xml на постгресе, а ему в ответ — не так сидишь, почерк кривой... Тот самый случай, когда за читателей стыдно.

Sign up to leave a comment.

Articles