Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
v. 9.7.2 Помогите, плз, разобраться. запрос: WITH TBL1 (TMP_IDIMP) AS (SELECT IDIMP FROM FINAL TABLE( UPDATE USRSCHEMA.TMPINHSP B SET B.ERR_EMPTY=1 WHERE B.IDIMP=222 AND B.ERR_EMPTY=0 AND PRFMED IS NULL )), TBL2 (ID) AS (SELECT ID FROM FINAL TABLE( UPDATE USRSCHEMA.IMPORT SET FLCSTATUS=-1 WHERE ID IN (SELECT TMP_IDIMP FROM TBL1) )) SELECT COUNT(*) FROM TBL2; выполняется без проблем. Если же его включить в хранимую процедуру: CREATE OR REPLACE PROCEDURE USRSCHEMA.MY_CHK (IN ID_IMP BIGINT) SPECIFIC MY_CHK LANGUAGE SQL MODIFIES SQL DATA ------------------------------------------------------------------------ P1: BEGIN WITH TBL1 (TMP_IDIMP) AS (SELECT IDIMP FROM FINAL TABLE( UPDATE USRSCHEMA.TMPINHSP B SET B.ERR_EMPTY=1 WHERE B.IDIMP=ID_IMP AND B.ERR_EMPTY=0 AND PRFMED IS NULL )), TBL2 (ID) AS (SELECT ID FROM FINAL TABLE( UPDATE USRSCHEMA.IMPORT SET FLCSTATUS=-1 WHERE ID IN (SELECT TMP_IDIMP FROM TBL1) )) SELECT COUNT(*) FROM TBL2; COMMIT; END P1@ то DB2 ругается на "неправильный элемент WITH". Почему? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 11:17 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
askfinder, Второй случай Begin End содержит! Db2 это вам не MSSQL и ни Sybase, select напрямую вернуть нельзя из процедуры. Используйте курсор, имхо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 11:48 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
medoed, С курсором работает, но как-то не хотелось бы его создавать. Меня собственно результат SELECT Count(*) не интересует, мне нужно лишь выполнить один UPDATE по результатам другого. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 11:58 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
askfindermedoed, С курсором работает, но как-то не хотелось бы его создавать. Меня собственно результат SELECT Count(*) не интересует, мне нужно лишь выполнить один UPDATE по результатам другого. Пишите вложенный запрос! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 12:14 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
askfinder, Ровно потому, что в процедуре нельзя просто писать select ... (куда оно результат то девать будет?): Код: sql 1. 2. 3. Можно так: Код: sql 1. 2. 3. 4. 5. т.е. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Но! Это очень, ОЧЕНЬ! криво хотя бы потому, что для вычислимости count(*) в общем случае нет необходимости инстанциировать таблицу (т.е. проводить сам UPDATE). Понятно и правильно желание работать с SET'ами, но хорошего альтернативного решения я с ходу не вижу (MERGE в данном случае не помошник). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 12:22 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
CawaSPbaskfinder, Ровно потому, что в процедуре DB2 и Oracle нельзя просто писать select ... (куда оно результат то девать будет?): . Поправел ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 12:33 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
CawaSPb, Пытался в процедуре сделать подзапросом: ... UPDATE USRSCHEMA.IMPORT SET FLCSTATUS=-1 WHERE ID IN ( SELECT IDIMP FROM FINAL TABLE( UPDATE USRSCHEMA.TMPINHSP B SET B.ERR_EMPTY=1 WHERE B.IDIMP=ID_IMP AND B.ERR_EMPTY=0 AND PRFMED IS NULL ) FETCH FIRST 1 ROW ONLY); COMMIT; ... Ругается на контекст UPDATE-а. В принципе, конечно можно разбить на два запроса: ... DECLARE TMPID BIGINT DEFAULT 0; SELECT IDIMP INTO TMPID FROM FINAL TABLE( UPDATE USRSCHEMA.TMPINHSP B SET B.ERR_EMPTY=1 WHERE B.IDIMP=ID_IMP AND B.ERR_EMPTY=0 AND PRFMED IS NULL ) FETCH FIRST 1 ROW ONLY; COMIT; UPDATE USRSCHEMA.IMPORT SET FLCSTATUS=-1 WHERE ID=TMPID; COMIT; ... Но хотелось бы все-таки одним запросом обновлять обе таблицы. Не соображу как это правильно сделать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 12:54 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
CawaSPbт.е. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Так тоже ругается - "Обнаружен неправльный элемент "AS" после текста "ITH TBL1 (TMP_IDIMP)". Список возможных правильных элементов: "JOIN" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 13:33 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
askfinderТак тоже ругается - ... "Действительно, Пятачок..." (C) Я смотрю результат "select from update" даже во временную таблицу не запихнуть. т.е. применение этой конструкции очень и очень ограничено, хотя каких-либо технических причин подобного ограничения я не вижу. Вариант - навесить на USRSCHEMA.TMPINHSP after update триггер. Тем более, это скорее всего будет наиболее точно отражать суть происходящего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 16:08 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
Как вариант, можно в declare globary temporary table (реальные темповые таблицы) сохранять результаты и с ними джойнить. Но не уверен, что это корректное решение, просто если это реально темповая таблица, то триггерами её обвешивать, не есть гут,имхо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.02.2014, 16:55 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
askfinder, Как-то так: Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2014, 08:52 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
Mark Barinstein, Спасибо, Марк. В таком виде все работает. Может подскажете, какой вариант: 1. WITH, завернутый в курсор 2. Два последовательных UPDATE. 3. Конструкция FOR выглядит более предпочтительным (производительным) в общем случае (при прочих равных условиях)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2014, 09:47 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
askfinder, Добрый день. Никто не сможет вам сказать для общего случая, как оно будет эффективнее. Только тестрование разных вариантов на конкретном примере может показать как оно эффективнее будет. В теории, если брать ваш пример, то вы на основе записей, которые вы обновили первым запросом: WITH TBL1 (TMP_IDIMP) AS (SELECT IDIMP FROM FINAL TABLE( UPDATE USRSCHEMA.TMPINHSP B SET B.ERR_EMPTY=1 WHERE B.IDIMP=ID_IMP AND B.ERR_EMPTY=0 AND PRFMED IS NULL ) делаете изменение в другой таблице: TBL2 (ID) AS (SELECT ID FROM FINAL TABLE( UPDATE USRSCHEMA.IMPORT SET FLCSTATUS=-1 WHERE ID IN (SELECT TMP_IDIMP FROM TBL1) )) Если вы вместо такой удобной конструкции будете реализовавать ту же самую логику по-другому, то вам, скорее всего, придется делать значительно больше IO. Ведь надо как-то запомнить, какие же именно записи изменились первым update, чтобы потом использовать их ID во втором. Для этого select from data change operations и делалось. Но на практике надо смотреть, приведет ли это действительно к выигрышу в производительности, т.к. никто не знает, как в общем случае поведет себя оптимизатор. Например, он может для такого 2-х этажного запроса выбрать table scan для USRSCHEMA.IMPORT по какой-то причине (например, ошибка в оценке кол-ва измененных записей), хотя если бы вы сохранили эти TMP_IDIMP во временной таблице и собрали бы на нее статистику, то он мог бы выбрать index scan для USRSCHEMA.IMPORT. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.02.2014, 10:53 |
|
||
|
неправильный элемент WITH в хранимой процедуре
|
|||
|---|---|---|---|
|
#18+
Mark Barinsteinaskfinder, хотя если бы вы сохранили эти TMP_IDIMP во временной таблице и собрали бы на нее статистику, то он мог бы выбрать index scan для USRSCHEMA.IMPORT. Сам нечто похожее советовал выше, но наткнулся на один неприятный факт. При вставке пару тысяч строк в темповую таблицу db2 занимает время порядка 5-ти секунд. В Mssql при вставке в нормальные темповые таблицы такой же структуры пары тысячи строк (#tmp) , это порядка 1-ой секунды занимало. Поэтому к темповым таблицам DB2 отношусь настороженно, там где важно быстродействие... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.02.2014, 12:42 |
|
||
|
|

start [/forum/topic.php?fid=43&msg=38570627&tid=1601153]: |
0ms |
get settings: |
7ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
177ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 13ms |
| total: | 279ms |

| 0 / 0 |
