|
|
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Доброго времени суток. Подскажите пожалуйста, как в PostgreSQL реализованы пакетные операции? Немного подробностей: Клиентское приложение написано на Delphi (если это важно) Приложение каждый день парсит файлы Excel и заносит инфу в БД. На каждую запись из файла excel приходятся следующие проверки: Считали строку (несколько ячеек) в переменные Формируем запрос на поиск совпадения АРтикулИзФайла и АртикулИзБазы Если совпадений нет, то добавляем запись Если найдено одно совпадение, то происходит проверка НаименованиеИзФайла и НаиманованиеИзБазы. Если есть различия, то вызывается UPDATE Мне посоветовали пакетные операции в PostgreSQL? но я не совсем понял как это реализуется в СУБД Я так понимаю, что на стороне клиента надо формировать либо запрос в памяти либо какой-то файл специального формата в каждой строчке которого будет вызываться INSERT (строка 1) INSERT (строка 2) А на стороне PostgreSQL как-то реализовать хранимую процедуру или триггер (так и не понял, что лучше), которая будет осуществлять все описанные выше операции ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 16:56:29 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
cr@nk, заливайте Excel во временную таблицу, а потом insert/update из временной таблицы. все равно перечитываете весь файл и дергаете базу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 17:17:25 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
V&N, Пара вопросов: Есть какое-то специальное понятие временной таблицы? Или имеется ввиду создавать таблицу, заливать туда данные, переносить их в новую таблицу, а ту временную удалять? Допустим, что есть 2 таблицы (основная и временная). Я не понимаю как их объединить с обновлением данных Условно структура такая: ID (serial), Article, Name, Date, Cost, Post (integer, подстановочное поле, берётся из другой таблицы). Остальные поля все типа text и именно они берутся из файла Excel В этой таблице поле Article не изменяется. Может поменяться Name, Cost и 100% поменяется Date на следующий день. Как PG произведёт слияние 2х таблиц? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 17:39:38 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Если это важно, то объём данных из файлов Excel самый разный. Может быть пара тысяч строк, а может доходить до 100 тыс строк ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 17:43:17 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
cr@nk , временная - CREATE TEMPORARY TABLE ... IF NOT EXISTS ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP ... - доступна в пределах сессии. UPDATE table FROM temp_table WHERE .... INSERT INTO table (col1, col2, col...) (SELECT col1, col2, col... FROM temp_table WHERE NOT EXISTS /NOT IN ..) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 17:52:35 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
cr@nkЕсли это важно, то объём данных из файлов Excel самый разный. Может быть пара тысяч строк, а может доходить до 100 тыс строк ну и что, а так вы пинаете базу на каждую сроку. а так три раза пнуть 1) залить лимон строк, 2) обновление расхождений 3) заливка нового. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 17:56:17 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
V&N, Спасибо за разъяснение. Получается никакие триггеры даже не нужны :) Ещё есть вопрос-уточнение про временные таблицы: 1. Надо ли внутри временной таблицы прописывать создание индексов? 2. По поводу жизни таблицы на время сессии. У меня может быть запущено несколько копий моей программы для обработки разных файлов Excel. Все они коннектятся с одним логином и паролем к БД. После обработки прога закрывается. Вот я и думаю, что будет, если прописать в программе жёстко одно и тоже имя для временной таблицы? Или лучше генерировать имя таблицы из случайного набора символов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 18:11:47 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
заливайте много строк сразу через команду COPY а вот эту логику сделайте в тригере FOR EACH ROW: cr@nkЕсли совпадений нет, то добавляем запись Если найдено одно совпадение, то происходит проверка НаименованиеИзФайла и НаиманованиеИзБазы. Если есть различия, то вызывается UPDATE ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 18:21:55 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
cr@nkV&N, Спасибо за разъяснение. Получается никакие триггеры даже не нужны :) Ещё есть вопрос-уточнение про временные таблицы: 1. Надо ли внутри временной таблицы прописывать создание индексов? 2. По поводу жизни таблицы на время сессии. У меня может быть запущено несколько копий моей программы для обработки разных файлов Excel. Все они коннектятся с одним логином и паролем к БД. После обработки прога закрывается. Вот я и думаю, что будет, если прописать в программе жёстко одно и тоже имя для временной таблицы? Или лучше генерировать имя таблицы из случайного набора символов? нужны/не нужны триггеры - вам решать. 1. Возможно понадобится на ключевые поля. explain analyze в помощь 2. Все равно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 18:32:39 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat, А вашего метода какие преимущества перед методом, предложенным выше? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 19:24:30 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatзаливайте много строк сразу через команду COPY Вы имеете ввиду приводить xls-файл к CSV формату и потом импортировать в таблицу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.06.2014, 21:21:08 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
cr@nkLeXa NalBat, А вашего метода какие преимущества перед методом, предложенным выше?мне кажется, упрощается интерфейс обновления данных в таблице. вы делаете из приложения просто INSERT или COPY. а всю работу за вас сделает тригер, вместо INSERT-а выполнит UPSERT. вот ваша задача упоминается в документации: http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE аналогичная задача возникла и у нас, но не обновлять справочник, а дополнять счетчики статистики. я сделал с использованием тригера, сейчас испольуется в бою: Код: 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. cr@nkLeXa NalBatзаливайте много строк сразу через команду COPYВы имеете ввиду приводить xls-файл к CSV формату и потом импортировать в таблицу?не нужно сохранять файл в формате csv. из вашего языка порграммирования вызываете функцию типа pg_copy(table_name, data). например perl, python предоставляют такую функцию. не знаю, умеет ли это драйвер дельфи, вот нагуглилось: тынц ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.06.2014, 02:45:04 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
cr@nk, Можно реализовать (insert/update) и без триггера через с помощью CTE, если версия PostgreSQL позволяет. Реализовывал подобное http://www.biwed.ru/index.php/dobryaki/16-sql/36-obnovlenie-zapisej-tablicy-izmerenij-pri-pomoshhi-cte С уважением, biwed.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.06.2014, 03:42:18 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
biwed.rucr@nk, Можно реализовать (insert/update) и без триггера через с помощью CTE, если версия PostgreSQL позволяет. Реализовывал подобное http://www.biwed.ru/index.php/dobryaki/16-sql/36-obnovlenie-zapisej-tablicy-izmerenij-pri-pomoshhi-cte Может быть мне не хватает грамотности в этом вопросе, но этот пример является просто развёрнутым ответом участника форума V&N LeXa NalBatмне кажется, упрощается интерфейс обновления данных в таблице. вы делаете из приложения просто INSERT или COPY. а всю работу за вас сделает тригер, вместо INSERT-а выполнит UPSERT. Да я тоже склоняюсь, что лучше основную работу возложить на сервер. Надо просто разобраться с командой COPY ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.06.2014, 06:55:50 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Пробую написать триггерную функцию для своей задачи. Пока получается вот что: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Получаю ошибку pgAdminОШИБКА: неверный синтаксис для типа date: "lastdate" LINE 1: SELECT 'lastdate'<=new.lastdate ^ QUERY: SELECT 'lastdate'<=new.lastdate CONTEXT: функция PL/pgSQL my_upsert(), строка 12, оператор IF ********** Ошибка ********** ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 08:55:52 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Если взять в кавычки и вторую часть выражения, то ошибка пропадает, но само сравнение не отрабатывает корректно. Попробовал менять new.lastdate на +/- 1 день. Запрос ниже всегда выполнялся Код: plsql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 09:54:42 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Конечно же, условие прописано ошибочное: Код: plsql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 10:44:28 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Мда... осознал, что функция в целом не работает Код: plsql 1. Подскажите пожалуйста, как это дело реализовать правильно... (сравнить переданное значение (new) с уже имеющимся) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 11:40:30 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
cr@nk, вам надо выбрать все поля строки, если такая имеется, из таблицы с интересующим значением artice. то есть вместо "SELECT COUNT(*) INTO _tovar_count FROM ..." надо делать что-то типа: SELECT _tovar INTO _found_tovar FROM _tovar WHERE article=new.article; и далее сравнивать new.name с _found_tovar.name и т.п. и еще, условие "WHERE id=id" тождественное, его тоже надо заменить. и, возможно, оставить таким же как в SELECT, то есть по artice, а не по id. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 14:31:17 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat, Спасибо за наводку. Вроде сейчас получил рабочую функцию Код: 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. Так и не смог понять, как другим способом получить количество полученных записей через Код: sql 1. Ещё бы как-то отладить это дело. Не вижу какие индексы использует функция и использует ли в принципе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 19:41:32 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Я может чего не понял, но что мешает реализовать всю эту функцию одним Update с логикой, чем разводить код типа Код: sql 1. который вернет ВСЕ поля в таблице и делать два UPDATE на позицию + обвязка логики. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 21:06:39 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Troglodit, Явная нехватка знаний в этой области. Подскажите пож-та как сделать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.06.2014, 21:14:28 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatмне кажется, упрощается интерфейс обновления данных в таблице. вы делаете из приложения просто INSERT или COPY. а всю работу за вас сделает тригер, вместо INSERT-а выполнит UPSERT. ну да, проще но сильно тормознее. p.s. триггеры зло! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.06.2014, 12:25:30 |
|
||
|
Пакетное добавление/обновление данных
|
|||
|---|---|---|---|
|
#18+
Ivan Durak, Я бы не сказал, что сильно проще. Вон, товарищ постом выше говорит, что всё решается как-то через 1 UPDATE... Это по скорости наверное космос будет в сочетании с правильными индексами. Надо просто замеры скорости сделать в обоих вариантах, но для начала надо триггерную функцию оптимизировать :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.06.2014, 13:03:31 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=38674593&tid=1998617]: |
0ms |
get settings: |
7ms |
get forum list: |
21ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
184ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 225ms |
| total: | 518ms |

| 0 / 0 |
