#sql #postgresql
#sql #postgresql
Вопрос:
Я новичок в PostgreSQL, но уже много лет работаю с MSSQL. В настоящее время я работаю с PostgreSQL 13.
В MSSQL у меня есть скрипт, который создает смещение для дат, чтобы я мог создать финансовый календарь в той же таблице дат, что и мой обычный календарь. Я просто добавляю смещение к дате в строке, и оно корректирует мой финансовый год по мере необходимости.
Я пытаюсь создать что-то подобное в PostgreSQL. У меня есть некоторый код, работающий, чтобы делать то, что я хочу. Однако сейчас я пытаюсь написать функцию или хранимую процедуру для автоматизации этого кода. У меня возникают проблемы с преобразованием кода для работы в функции или хранимой процедуре.
Мой код, над которым я работаю, выглядит следующим образом. Это очень урезанная версия кода для иллюстрации.
DO $$
DECLARE daydiff INTERVAL;
DECLARE startdate DATE;
DECLARE enddate DATE;
DECLARE fiscalstartdate DATE;
BEGIN
-- Populate these variables
startdate:=(date '2017-01-01');
enddate:=(date '2017-12-31');
fiscalstartdate:=(date '2016-09-01');
-- Calculate date diff
daydiff:=make_interval(days => startdate - fiscalstartdate);
-- Insert records into table
INSERT INTO master.Calendar (
full_date
, year
, fiscal_year
)
SELECT
CAST(generate_series AS date) AS full_date
, EXTRACT(YEAR FROM generate_series)::INTEGER AS year
, EXTRACT(YEAR FROM generate_series daydiff)::INTEGER AS fiscal_year
FROM (
SELECT generate_series(
startdate::timestamp,
enddate::timestamp,
interval '1 days'
)
) a;
END $$;
Он делает именно то, что я хочу сделать. Однако я хочу иметь возможность вызывать это в функции или хранимой процедуре для автоматизации перестройки таблиц и данных. Затем я попробовал несколько разных вещей, но сейчас я нахожусь вот в чем. Опять же, это урезанная версия, но проблема все еще присутствует.
CREATE OR REPLACE PROCEDURE create_calendar_table(startdate DATE, enddate DATE, fiscalstartdate DATE) AS $$
DECLARE
daydiff INTERVAL;
BEGIN
-- Calculate date diff
daydiff:=make_interval(days => startdate - fiscalstartdate);
-- Insert records into table
INSERT INTO master.Calendar (
full_date
, year
, fiscal_year
)
SELECT
CAST(generate_series AS date) AS full_date
, EXTRACT(YEAR FROM generate_series)::INTEGER AS year
, EXTRACT(YEAR FROM generate_series daydiff)::INTEGER AS fiscal_year
FROM (
SELECT generate_series(
startdate::timestamp,
enddate::timestamp,
interval '1 days'
)
) a;
END $$ LANGUAGE SQL;
Я получаю сообщение об ошибке «синтаксическая ошибка на «ИНТЕРВАЛЕ» или рядом с ним». Я пробовал несколько вещей, например, пытался добавить туда DO $$, и это, похоже, вообще не сработало. Очень хорошо может быть мое невежество в этой версии SQL. Лучшее, что я могу сказать, это то, что я не могу объявить тип ИНТЕРВАЛА при создании процедуры или функции, как я могу в DO $$ .
Как я могу обойти это или как правильно это сделать в PostgreSQL? Любая помощь приветствуется.
Комментарии:
1. Не связано, но:
declare
запускает блок, вам нужно использовать его только один раз для всех переменных, а не по одной для каждой переменной.2. Спасибо, это полезно знать. Я ценю вашу помощь.
Ответ №1:
Вам нужно language plpgsql
— вы не можете использовать переменные внутри функции SQL.
Комментарии:
1. Я не понимал, что там может быть несколько языков, которые можно использовать. Это интересно . Мне нужно будет прочитать об этом подробнее. Еще раз спасибо за вашу помощь.
2. @Kupokev postgresql.org/docs/current/xplang.html