Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
Здравствуйте, хочу спросить совета. Собственно проблема: Существует функция в которой создаются временные таблицы и происходит работа с ними. При повторном обращении к этой функции, если предыдущий вызов функции еще в работе, то происходит работа с теми же таблицами которые были созданы при первом обращении к функции и не успели удалиться ( либо ошибка повторного создания таблицы с тем же именем, в зависимости от команды создания таблицы). Как сделать так, чтобы для каждого вызова функции использовалась своя временная таблица? З.Ы. динамические запросы с созданием уникальных имен таблиц не годятся, так как теряется тот выигрыш производительности ради которого была написана функция. Оба вызова должны происходить в одной и той же сессии. Вот пример подобного случая. Удаление временных таблиц в конце функций убрал специально, чтобы было видно, что по завершению работ обоих функций они работали с одной и той же таблицей. Код: 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. Запрос SELECT * FROM test2; выдает две строки. Если вызов IF NOT EXISTS во второй функции убрать, просто будет ошибка "отношение существует". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 13:08 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOneЗдравствуйте, хочу спросить совета. Собственно проблема: Существует функция в которой создаются временные таблицы и происходит работа с ними. При повторном обращении к этой функции, если предыдущий вызов функции еще в работе, то происходит работа с теми же таблицами которые были созданы при первом обращении к функции и не успели удалиться ( либо ошибка повторного создания таблицы с тем же именем, в зависимости от команды создания таблицы). Как сделать так, чтобы для каждого вызова функции использовалась своя временная таблица? З.Ы. динамические запросы с созданием уникальных имен таблиц не годятся, так как теряется тот выигрыш производительности ради которого была написана функция. Оба вызова должны происходить в одной и той же сессии. Вот пример подобного случая. Удаление временных таблиц в конце функций убрал специально, чтобы было видно, что по завершению работ обоих функций они работали с одной и той же таблицей. Код: 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. Запрос SELECT * FROM test2; выдает две строки. Если вызов IF NOT EXISTS во второй функции убрать, просто будет ошибка "отношение существует". используйте разные имена, вы сами уперлись в свой дизайн. Определитесь - вам нужна одна и та же таблица или разные? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 13:44 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
Ролг ХупинNumberOneЗдравствуйте, хочу спросить совета. Собственно проблема: Существует функция в которой создаются временные таблицы и происходит работа с ними. При повторном обращении к этой функции, если предыдущий вызов функции еще в работе, то происходит работа с теми же таблицами которые были созданы при первом обращении к функции и не успели удалиться ( либо ошибка повторного создания таблицы с тем же именем, в зависимости от команды создания таблицы). Как сделать так, чтобы для каждого вызова функции использовалась своя временная таблица? З.Ы. динамические запросы с созданием уникальных имен таблиц не годятся, так как теряется тот выигрыш производительности ради которого была написана функция. Оба вызова должны происходить в одной и той же сессии. Вот пример подобного случая. Удаление временных таблиц в конце функций убрал специально, чтобы было видно, что по завершению работ обоих функций они работали с одной и той же таблицей. Код: 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. Запрос SELECT * FROM test2; выдает две строки. Если вызов IF NOT EXISTS во второй функции убрать, просто будет ошибка "отношение существует". используйте разные имена, вы сами уперлись в свой дизайн. Определитесь - вам нужна одна и та же таблица или разные? Это в примере я привел две разные функции, чтобы было нагляднее. На деле функция одна, но может вызывается несколько раз в одно и то же время, соответственно и у таблиц названия будут одинаковые. Если название временной таблицы генерировать в каждом вызове уникальное, с помощью динамических запросов, то теряется производительность, как я уже писал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 14:02 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOneесли предыдущий вызов функции еще в работеВременные таблицы "не нужны". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 14:12 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOneРолг Хупинпропущено... используйте разные имена, вы сами уперлись в свой дизайн. Определитесь - вам нужна одна и та же таблица или разные? Это в примере я привел две разные функции, чтобы было нагляднее. На деле функция одна, но может вызывается несколько раз в одно и то же время, соответственно и у таблиц названия будут одинаковые. Если название временной таблицы генерировать в каждом вызове уникальное, с помощью динамических запросов, то теряется производительность, как я уже писал. "Как сделать так, чтобы для каждого вызова функции использовалась своя временная таблица? " и так плохо, и так плохо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 14:18 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
Ролг ХупинNumberOneпропущено... Это в примере я привел две разные функции, чтобы было нагляднее. На деле функция одна, но может вызывается несколько раз в одно и то же время, соответственно и у таблиц названия будут одинаковые. Если название временной таблицы генерировать в каждом вызове уникальное, с помощью динамических запросов, то теряется производительность, как я уже писал. "Как сделать так, чтобы для каждого вызова функции использовалась своя временная таблица? " и так плохо, и так плохо. p2.NumberOneесли предыдущий вызов функции еще в работеВременные таблицы "не нужны". Как обойтись без временных таблиц, если происходит копирование сущностей со множеством связей на другие таблицы, в том числе рекурсивными, особенно, если требуется предварительная проверка на то, что сущность уже существует (доскональная проверка всех ее связей, в том числе рекурсивных, если есть какие-то расхождения, то копирование вообще не должно происходить). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 14:30 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOneКак обойтись без Возвращать результат непосредственно из функции, как и заявлено в приведенной тобой декларации. И поменьше фантазировать по поводу существования временной таблицы в "одно и то же время". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 16:03 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
Решил попробовать переписать с использованием WITH. Столкнулся с проблемой. Во временную таблицу вставляются некоторые данные, затем в этих данных обновлялось некое поле, после проводилась проверка, что если хоть в одной строке таблицы в этом поле будет NULL то производился выход из функции с возвратом кода ошибки. Если все было нормально, то данные из временной таблицы копировались в нужную таблицу. Так вот с конструкцией WITH вместо вставки во временную таблицу делаю WITH temp_table AS ( SELECT ...), up_table (UPDATE temp_table ...), XXX INSERT INTO chosen_table FROM temp_table. Так вот, как вместо этих XXX, устроить проверку на NULL, и в случае не выполнения условия не допустить вставки в таблицу chosen_table. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 16:10 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
p2.NumberOneКак обойтись без Возвращать результат непосредственно из функции, как и заявлено в приведенной тобой декларации. И поменьше фантазировать по поводу существования временной таблицы в "одно и то же время". т.е. не может одна функция быть запущена несколько раз в одно и тоже время в одной сессии? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 16:14 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOnep2.пропущено... Возвращать результат непосредственно из функции, как и заявлено в приведенной тобой декларации. И поменьше фантазировать по поводу существования временной таблицы в "одно и то же время". т.е. не может одна функция быть запущена несколько раз в одно и тоже время в одной сессии? Нет конечно. Это физически не возможно. В одно время в одной сессии только что то одно может работать. -- Maxim Boguk dataegret.ru - лучшая русскоязычная поддержка PostgreSQL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 16:17 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
Maxim BogukNumberOneпропущено... т.е. не может одна функция быть запущена несколько раз в одно и тоже время в одной сессии? Нет конечно. Это физически не возможно. В одно время в одной сессии только что то одно может работать. -- Maxim Boguk dataegret.ru - лучшая русскоязычная поддержка PostgreSQL Спасибо за информацию. Все равно решил попробовать избавиться от временных таблиц, так что повторю вопрос из прошлого поста. Решил попробовать переписать с использованием WITH. Столкнулся с проблемой. Во временную таблицу вставляются некоторые данные, затем в этих данных обновлялось некое поле, после проводилась проверка, что если хоть в одной строке таблицы в этом поле будет NULL то производился выход из функции с возвратом кода ошибки. Если все было нормально, то данные из временной таблицы копировались в нужную таблицу. Так вот с конструкцией WITH вместо вставки во временную таблицу делаю WITH temp_table AS ( SELECT ...), up_table (UPDATE temp_table ...), XXX INSERT INTO chosen_table FROM temp_table. Так вот, как вместо этих XXX, устроить проверку на NULL, и в случае не выполнения условия не допустить вставки в таблицу chosen_table. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 16:56 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOne, эээ а добавить в INSERT условие WHERE чегоужвамтамнадо IS NOT NULL? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 17:00 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
Maxim BogukNumberOne, эээ а добавить в INSERT условие WHERE чегоужвамтамнадо IS NOT NULL? IS NOT NULL не подойдет потому, что в случае, если хотя бы один NULL в какой-то строке, то уже не надо вставлять все строки, а не только ту в которой нашелся NULL. Предположим если я сделаю дополнительный код в WITH , вроде ..., null_count AS (SELECT COUNT(*) AS ncount FROM temp_table WHERE my_var IS NULL, а потом при вставке в WITH к нему буду обращаться, вроде ... INSERT chosen_table FROM temp_table, null_count WHERE null_count.ncount >0. Синтаксис не правильный, наверно, но примерный. Не знаю, вообще можно ли, как-нибудь так написать. Но, в общем, даже, если это сработает. Как, в случае, если там все-таки были NULL'ы потом завершить функцию с соответствующим кодом ошибки, а не обычным образом. (Проверкой, что в chosen_table добавились новые строки?) При том, что необходимо вставить данные в этом же WITH еще в несколько таблиц связанных, и так же должно пройти еще несколько проверок (в этом же with) на подобие проверок на NULL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2017, 17:23 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOneMaxim BogukNumberOne, эээ а добавить в INSERT условие WHERE чегоужвамтамнадо IS NOT NULL? IS NOT NULL не подойдет потому, что в случае, если хотя бы один NULL в какой-то строке, то уже не надо вставлять все строки, а не только ту в которой нашелся NULL. Предположим если я сделаю дополнительный код в WITH , вроде ..., null_count AS (SELECT COUNT(*) AS ncount FROM temp_table WHERE my_var IS NULL, а потом при вставке в WITH к нему буду обращаться, вроде ... INSERT chosen_table FROM temp_table, null_count WHERE null_count.ncount >0. Синтаксис не правильный, наверно, но примерный. Не знаю, вообще можно ли, как-нибудь так написать. Но, в общем, даже, если это сработает. Как, в случае, если там все-таки были NULL'ы потом завершить функцию с соответствующим кодом ошибки, а не обычным образом. (Проверкой, что в chosen_table добавились новые строки?) При том, что необходимо вставить данные в этом же WITH еще в несколько таблиц связанных, и так же должно пройти еще несколько проверок (в этом же with) на подобие проверок на NULL. Да, то что я написал выше работает, но мне необходим совет для решения следующих проблем. Ниже приведен упрощенный (неработающий) вариант функции. Происходит копирование некой сущности (objects) с подчиненными данными (first_table, second_table). Некоторые таблицы подчиненных данных не копируются в том случае если такие же подчиненные данные уже существуют в данной таблице. Тогда происходит только запоминание соответствий idшников. Функция должна вернуть таблицу: в случае успешного копирования должно быть две строки (в приведенном ниже примере) об успехе двух инсертов, в случае неуспеха одна строка с ошибкой. Теперь вопросы: 1) После определения count_table.null_count, если значение не нулевое то дальнейшие вставки не нужны, а только вывод строки с ошибкой, сейчас вставки и не происходят благодаря приписыванию "FROM count_table WHERE count_table.null_count = 0" или "JOIN count_table ON count_table.null_count = 0". Но получается происходят ненужные проверки, так как функция уже ничего не должна делать. (В настоящей функции после этой проверки еще шагов 7 происходит со вставками(а в примере только 2)). Вопрос как приостановить выполнение из конструкции WITH или как переделать функцию, чтобы этого избежать? 2) Можно ли так UNION использовать "SELECT * FROM return_error_string UNION SELECT * FROM return_string1 UNION SELECT * FROM return_string2" для заполнения возвращаемой таблицы? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2017, 17:45 |
|
||
|
Проблема с временной таблицей
|
|||
|---|---|---|---|
|
#18+
NumberOneNumberOneпропущено... IS NOT NULL не подойдет потому, что в случае, если хотя бы один NULL в какой-то строке, то уже не надо вставлять все строки, а не только ту в которой нашелся NULL. Предположим если я сделаю дополнительный код в WITH , вроде ..., null_count AS (SELECT COUNT(*) AS ncount FROM temp_table WHERE my_var IS NULL, а потом при вставке в WITH к нему буду обращаться, вроде ... INSERT chosen_table FROM temp_table, null_count WHERE null_count.ncount >0. Синтаксис не правильный, наверно, но примерный. Не знаю, вообще можно ли, как-нибудь так написать. Но, в общем, даже, если это сработает. Как, в случае, если там все-таки были NULL'ы потом завершить функцию с соответствующим кодом ошибки, а не обычным образом. (Проверкой, что в chosen_table добавились новые строки?) При том, что необходимо вставить данные в этом же WITH еще в несколько таблиц связанных, и так же должно пройти еще несколько проверок (в этом же with) на подобие проверок на NULL. Да, то что я написал выше работает, но мне необходим совет для решения следующих проблем. Ниже приведен упрощенный (неработающий) вариант функции. Происходит копирование некой сущности (objects) с подчиненными данными (first_table, second_table). Некоторые таблицы подчиненных данных не копируются в том случае если такие же подчиненные данные уже существуют в данной таблице. Тогда происходит только запоминание соответствий idшников. Функция должна вернуть таблицу: в случае успешного копирования должно быть две строки (в приведенном ниже примере) об успехе двух инсертов, в случае неуспеха одна строка с ошибкой. Теперь вопросы: 1) После определения count_table.null_count, если значение не нулевое то дальнейшие вставки не нужны, а только вывод строки с ошибкой, сейчас вставки и не происходят благодаря приписыванию "FROM count_table WHERE count_table.null_count = 0" или "JOIN count_table ON count_table.null_count = 0". Но получается происходят ненужные проверки, так как функция уже ничего не должна делать. (В настоящей функции после этой проверки еще шагов 7 происходит со вставками(а в примере только 2)). Вопрос как приостановить выполнение из конструкции WITH или как переделать функцию, чтобы этого избежать? 2) Можно ли так UNION использовать "SELECT * FROM return_error_string UNION SELECT * FROM return_string1 UNION SELECT * FROM return_string2" для заполнения возвращаемой таблицы? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Решить удалось только с помощью использования массивов. Тему можно закрывать. Спасибо всем, кто помогал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.08.2017, 01:12 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=39501875&tid=1996267]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
62ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 14ms |
| total: | 169ms |

| 0 / 0 |
