Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273

Как концептуально сделать заполнение шаблона на основе таблицы?

24.11.2021, 19:26. Показов 1080. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имеется БД примерно следующего вида (см. картинку). Если коротко, в ней хранится информация о различных компонентах, из которых по определенному алгоритму собирают изделие. Перечень компонентов меняется в зависимости от параметров изделия (например, собираем установку мощности N, для нее нужны такие-то автоматы, такие-то провода, столько-то еще чего-нибудь).

Сам перечень элементов (Elements list) - выходной продукт работы программы по подборке комплектующих. Он уже частично заполнен и, как я решил, удобно ложится в СУБД.

На выходе нужно пустые поля в нем (Elements list) заменить на конкретные комплектующие и выгнать на печать (да хоть в .txt пока, не важно). Сам результат в базу записывать не надо, по словам заказчика.

Как лучше все это делать? Создавать временную таблицу и в ней компоновать уже все, чтобы потом распечатать? Или построчно читать шаблон и перегонять в файл, попутно обрабатывая незаполненные поля (может быть сложно из-за возникающих зависимостей при заполнении шаблона)?

Ссылки на ресурсы приветствуются.
Миниатюры
Как концептуально сделать заполнение шаблона на основе таблицы?  
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.11.2021, 19:26
Ответы с готовыми решениями:

Как концептуально правильно сделать переход и поддержку разных версий БД ?
Есть десктопное приложение C# + Entity Framework (подход Code First) + MS SQL Compact Пользователи могут обмениваться данными (видимо...

Заполнение таблицы на основе другой таблицы
Есть 2 документа. Заполняется документ №1 (допустим содержит pk:doc1_id), документ №2 (содержит pk:doc2_id и fk:doc1_id). Мне надо чтобы...

Заполнение данными таблицы шаблона Rtf, открытого в richEditControl
Всем привет! Хелп! Имею шаблон документа, сделанный в RTF. Благополучно его открываю в richEdit DevExpress, с помощью ReplaceAll заменяю...

7
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
25.11.2021, 08:45
А postgresql при чем здесь? Добавлять недостающие позиции и вообще делать что хочешь с полученным из базы набором данных будешь программно
0
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273
25.11.2021, 12:00  [ТС]
Цитата Сообщение от Аватар Посмотреть сообщение
А postgresql при чем здесь?
Вопрос в том, какой подход оптимальный.

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

Понятно, что работать оно будет. Просто, возможно, я в Москву через Владивосток еду.
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
25.11.2021, 12:06
Временная таблица в базе для таких целей это точно в Москву через Владивосток )
1
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273
25.11.2021, 12:08  [ТС]
Аватар, как тогда поступить? Запоминать, какие ячейки менял в шаблоне, чтобы после печати откатывать обратно?

Добавлено через 57 секунд
Шаблон там на 40 строчек, конечно, но копировать его не есть гут, да.
0
1265 / 979 / 384
Регистрация: 02.09.2012
Сообщений: 3,026
25.11.2021, 22:25
Начните с запроса. Вы одним запросом можете составить нужный Вам список комплектующих по заданным параметрам??
В этом случае не нужны временные таблицы.
Тогда результат этого запроса возвращайте в клиентскую программу и там уже что хотите - хоть на экран, хоть в файл.
1
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273
26.11.2021, 08:42  [ТС]
grgdvo, насчет запроса (точнее, его сложности) не уверен. Не знаю, как склеить результирующую таблицу.

Пока написаны примерно такие хранимые процедуры (сроки горят, а сдавать надо).

Инверторы (подъема, тележки, моста):

Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
CREATE OR REPLACE PROCEDURE fill_invertor
(
    invertor_type VARCHAR(63), 
    invertor_power REAL
)
AS $$ 
DECLARE
    source_id INTEGER = 
    (
        SELECT ID
        FROM 
        (
            SELECT 
                Element.ID AS ID, 
                Element.specification AS specification,
                Element.power AS POWER
            FROM Invertor 
            JOIN Element ON Invertor.element_id = Element.ID
        ) Invertor_combined
        WHERE 
            Invertor_combined.specification = invertor_type AND
            Invertor_combined.power = invertor_power
        LIMIT 1
    );
BEGIN
    RAISE NOTICE 'Source id = %', source_id;
 
    UPDATE Temp
    SET
        manufacturer_id = Invertor_info.manufacturer_id,
        TYPE = Invertor_info.type
    FROM
    (
        SELECT 
            TYPE, 
            manufacturer_id
        FROM Invertor 
        JOIN Element ON Invertor.element_id = Element.ID
        WHERE Element.ID = source_id
    ) Invertor_info
    WHERE 
        Temp.name LIKE invertor_type AND
        Temp.type IS NULL;
END; $$
LANGUAGE plpgsql;


Автомат защиты двигателя:

Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
CREATE OR REPLACE PROCEDURE fill_motor_protection_CB
(
    power_prefix VARCHAR(1),
    power_value REAL
)
AS $$ 
DECLARE
    source_id INTEGER = 
    (
        SELECT ID
        FROM 
        (
            SELECT 
                Element.ID AS ID, 
                Element.power AS POWER
            FROM Motor_protection_CB 
            JOIN Element ON 
                Motor_protection_CB.element_id = Element.ID
        ) mpcb_combined
        WHERE 
            mpcb_combined.power = power_value
        LIMIT 1
    );
BEGIN
    RAISE NOTICE 'Source id = %', source_id;
 
    UPDATE Temp
    SET
        TYPE = mpcb_info.type
    FROM
    (
        SELECT 
            TYPE
        FROM Element
        WHERE Element.ID = source_id
    ) mpcb_info
    WHERE 
        Temp.name = 'АВТОМАТ ЗАЩИТЫ ДВИГАТЕЛЯ' AND
        SUBSTRING(Temp.position, 1, 1) = power_prefix AND
        Temp.type IS NULL;
END; $$
LANGUAGE plpgsql;


Автоматический выключатель (с поворотной рукояткой):

Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
CREATE OR REPLACE PROCEDURE fill_CB_and_handle
(
    power_value REAL
)
AS $$ 
DECLARE
    dest_CB_type VARCHAR(63);
    dest_handle_type VARCHAR(63);   
BEGIN
    SELECT 
        element_types.type,
        element_types.rotary_handle
    INTO
        dest_CB_type,
        dest_handle_type
    FROM
    (
        SELECT 
            TYPE,
            rotary_handle
        FROM CB 
        JOIN Element ON Element.ID = CB.element_id
        WHERE POWER = power_value
    ) element_types;
 
    RAISE NOTICE 'CB = %, handle = %', dest_CB_type, dest_handle_type;
 
    UPDATE Temp
    SET
        TYPE = dest_CB_type
    WHERE 
        Temp.name = 'АВТОМАТИЧЕСКИЙ ВЫКЛЮЧАТЕЛЬ' AND
        Temp.type IS NULL;
        
    UPDATE Temp
    SET
        TYPE = dest_handle_type
    WHERE 
        Temp.name = 'ПОВОРОТНАЯ РУКОЯТКА' AND
        Temp.type IS NULL;
END; $$
LANGUAGE plpgsql;


Контактор:

Кликните здесь для просмотра всего текста

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE OR REPLACE PROCEDURE fill_contactor
(
    power_value REAL
)
AS $$   
BEGIN
    UPDATE Temp
    SET
        TYPE = 
        (
            SELECT TYPE
            FROM Contactor
            JOIN Element ON
                Element.ID = Contactor.element_id
            WHERE POWER = power_value           
        )
    WHERE 
        Temp.name = 'КОНТАКТОР' AND
        Temp.type IS NULL;
END; $$
LANGUAGE plpgsql;


Выключатель защиты:

Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE OR REPLACE PROCEDURE fill_CB
(
    power_value REAL
)
AS $$   
BEGIN
    UPDATE Temp
    SET
        TYPE = 
        (
            SELECT TYPE
            FROM CB
            JOIN Element ON
                Element.ID = CB.element_id
            WHERE POWER = power_value           
        )
    WHERE 
        Temp.name = 'ВЫКЛЮЧАТЕЛЬ ЗАЩИТЫ' AND
        Temp.type IS NULL;
END; $$
LANGUAGE plpgsql;


И еще несколько в том же духе. Для конкретных элементов в шаблоне, где тип IS NULL, надо (обычно по префиксу мощности) из таблицы элементов данного типа найти подходящий (он пока что всегда один, на мою удачу). Сегодня добавится таблица, где придется временные параметры для тормозных резисторов учитывать.

Не представляю, как это в один запрос слить.

Добавлено через 7 минут
Можно из процедур попробовать вырвать запросы в виде VIEW и что-то комбинировать, наверное... Все найденные примеры с выборкой и заменой значений делаются UPDATE-ом. Не похоже на то, что нужно.
0
1265 / 979 / 384
Регистрация: 02.09.2012
Сообщений: 3,026
28.11.2021, 09:33
Лучший ответ Сообщение было отмечено Ksardas_178 как решение

Решение

Есть конструкция WITH и UNION (просто с UNION будет план меньше, по производительности особых выигрышей не будет)

SQL
1
2
3
4
5
SELECT * FROM ...    -- подбор деталей тип1
UNION ALL
SELECT * FROM ...    -- подбор деталей тип2
UNION ALL
SELECT ...
или

SQL
1
2
3
4
5
6
7
WITH
подбор_деталей_тип1 AS (SELECT ....),
подбор_деталей_тип2 AS (SELECT ....)
SELECT * FROM подбор_деталей_тип1
UNION
SELECT * FROM подбор_деталей_тип2
...
У каждого подзапроса придется сделать одинаковый набор полей (соответствует вашей временной таблице: имя, тип, id еще что-то вы заполняете в функциях).

Будет выглядеть громоздко. Но вы точно избавитесь от временной таблицы, Избавитесь от UPDATE-ов, которые в PG далеко не быстрые И работать будет точно быстрее. Да, запрос большой будет, но это только чтение, которые Вы и так совершаете в разных функциях.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.11.2021, 09:33
Помогаю со студенческими работами здесь

Заполнение таблицы на основе адресов ее ячеек
Здравствуйте, есть необходимость выполнить простую, вроде бы, задачу, но ничего у меня не получается. Суть в следующем: Есть текстовый...

Как сделать выборку из таблицы на основе данных текущего юзера?
Собственно, вот. Имею проектик в ASP.NET с базой данных и авторизацией, работающей через EntityFramework. Стала задача: в контроллере надо...

Триггер на заполнение столбца таблицы на основе другой
Есть две таблицы: 1. Клиенты (код клиента, ФИО, количество дел) 2.Дела клиентов (номер дела, код клиента) У клиента может быть...

Как сделать заполнение таблицы из txt в datagridview
Как можно сделать так, чтобы из файла где все записано через пробел, чтобы автоматически заполнилась по нажатию кнопки в datagridview ...

Автоматическое заполнение таблицы на основе значения разности 2-х ячеек
Помогите пожалуйста! Необходимо проставить значения полей F:J соответствующими значениями из поля D, в зависимости от разности полей F1 и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru