Задача: обновить все записи одной таблицы, на основании данных другой таблицы. Причем условие сложное, которое просто в запрос update from select не впехнешь
Решение: сделаем функцию, которая собственно будет последовательно перебирать таблицу, и обновлять данные
CREATE OR REPLACE FUNCTION public.update_epd_cancel()
RETURNS int4
LANGUAGE plpgsql
AS $function$
DECLARE
crsr CURSOR FOR SELECT * FROM refusals; -- курсор для запроса
emp RECORD;
BEGIN
OPEN crsr; -- открываем курсор
LOOP
FETCH crsr INTO emp; -- извлекаем следующую строку в переменную
EXIT WHEN NOT FOUND; -- если строк больше нет — выходим
update ls set dt_cancel_epd_bill=emp.dt where ls.id=emp.ls; -- обработка строки
update ls set dt_cancel_epd_bill=emp.dt where ls.id=emp.ls_epd; -- обработка строки
END LOOP;
CLOSE crsr; -- закрываем курсор
return 0;
END;
$function$
;
Как то упустил эту возможность платформы 1С и никогда ранее не использовал. А тут вдруг прилетела задача поработать файлами большого размера (xlsx, csv), на основании данных в которых нужно строить различного вида отчёты. Пришла мысль: а почему бы не загрузить данные этих файлов в БД, а затем уже спокойно стоить на основании этих данных отчёты. Какие-то регистры, справочники и т.п. создавать в конфигурации для этого посчитал излишним. Самое правильное, подумал я, хранить всё вообще в какой-то сторонней базе (в моём случае в PostgreSQL). А 1С использовать только для вывода и формирования отчётов. Вот тут то я и вспомнил, что когда то мельком читал про «внешние источники данных» в 1С. Значит пришло время попробовать хранение информации во внешних источниках данных.
Сначала создам БД, с таблицами ls и shemes со структурой вида::
, где id — автоинкримент типа integer. Забегая вперед, следует отметить, что 1С не умеет при добавлении данных во внешние источники данных, передавать инкрементальное значение, а потому создадим триггер, который будет выполнятся перед транзакцией запроса INSERT, и заменяет значение id, на следующее по порядку:
Подготовка закончена. Теперь подготовим платформу 1С. А именно необходимо установить драйвер ODBC. Под Linux ставим из репозитария, под Windows скачиваем и устанавливаем отсюда: https://www.postgresql.org/ftp/odbc/releases/REL-16_00_0005-mimalloc/
Далее необходимо зайти в конфигуратор 1С и добавить новый источник данных и таблицу в нём. При создании таблицы, необходимо выбрать «Выбрать из списка таблиц внешнего источника данных», и построить строку соединения с БД, вида:
После чего, будут доступны для добавления в конфигуратор таблицы БД:
После того как нажмем «Готово», в конфигураторе будет что-то вроде:
Далее остаётся научится читать,писать и удалять эти данные:
// добвление
новыелс=внешниеисточникиданных.ОтчетыДля1С.Таблицы.reports_1c_public_ls.СоздатьОбъект();
новыелс.name="4232344";
новыелс.Записать();
// изменение
мХарактеристика = внешниеисточникиданных.ОтчетыДля1С.Таблицы.reports_1c_public_ls.НайтиПоПолю("id",3);
мОбъект = мХарактеристика.ПолучитьОбъект();
мОбъект.name = "Уря! Чебуршка родил слона!";
мОбъект.Записать();
//удаление
мХарактеристика = внешниеисточникиданных.ОтчетыДля1С.Таблицы.reports_1c_public_ls.НайтиПоПолю("id",3);
мОбъект = мХарактеристика.ПолучитьОбъект();
мОбъект.Удалить();
// чтение
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| reports_1c_public_ls.id КАК id,
| reports_1c_public_ls.name КАК name,
| reports_1c_public_shemes.name КАК name1
|ИЗ
| ВнешнийИсточникДанных.ОтчетыДля1С.Таблица.reports_1c_public_ls КАК reports_1c_public_ls
| ЛЕВОЕ СОЕДИНЕНИЕ ВнешнийИсточникДанных.ОтчетыДля1С.Таблица.reports_1c_public_shemes КАК reports_1c_public_shemes
| ПО reports_1c_public_ls.sheme = reports_1c_public_shemes.id";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
сообщить(ВыборкаДетальныеЗаписи.name);
сообщить(ВыборкаДетальныеЗаписи.name1);
КонецЦикла;
Update 16/09/2025: таки автоувеличение идентификатора умеет. Достаточно его указать как «только чтение» в 1С:
Задача: перенести рабочий, наполненный постами, сайт на движке WordPress с БД MySQL на PostgreeSQL
Инструментарий:
1) pgloader — утилита для переноса данных из баз данных MySQL в PostgreeSQL
Особенности о которые спотыкался:
для успешного переноса необходимо чтобы пользователь в терминале под которым осуществляется перенос имел максимальные права в БД и имел доступ «без пароля» для входа в консоль pgsql
при переносе создается схема с именем БД, а не заливается по умолчанию в схему public. Что в принципе для нашей ситуации даже будет плюсом.
Перед переносом, БД уже должна быть создана в PostgreeSQL
2) Плагин PG4WP который на «лету» исправляет запросы к MySQL на PostgreeSQL
Особенности:
работает только при «чистой» установке. Т.е. WordPress должен быть штатно проинсталлирован с нуля
Инсталляция корректно работает только до версии WordPress 5.9
Плагин заброшен, последнее обновление — 3 года назад
Итак, общий алгоритм переноса рабочего WordPress получается такой:
Переносим при помощи pgloader БД в отдельную схему
Заново устанавливаем WordPress 5.9 с плагином PG4WP
Удаляем из схемы public wp_posts (это если только статьи переносим) и переносим её из схемы созданной pgloader в public
Пробуем обновить штатно WordPress
Точно понадобится:
-- перенос таблицы из отдной схемы в другую
ALTER TABLE wp_base.wp_users
SET SCHEMA public
Удаление всех таблиц в схеме:
-- удаляем таблицы
DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
EXECUTE 'DROP TABLE ' || quote_ident(r.tablename) || ' CASCADE';
END LOOP;
END $$;
-- удаляем последовательности
DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT relname FROM pg_class where relkind = 'S') LOOP
EXECUTE 'DROP SEQUENCE IF EXISTS ' || quote_ident(r.relname) || ' CASCADE';
END LOOP;
END $$;
Поменять схему всех таблиц:
DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = 'старая_схема') LOOP
EXECUTE 'ALTER TABLE старая_схема.' || quote_ident(r.tablename) || ' SET SCHEMA новая_схема ';
END LOOP;
END $$;