Update таблички

golem59
Дата: 07.11.2008 12:37:40
Есть табличка примерно следующего вида:
tab
PK Page Pole1
1   1     'a'
2   1     'b'
3   2     'c'
4   2     'a'
5   3     '123'

Надо изменять поле page в зависимости от различных факторов. Например изменяем порядок отображения записей и должно получиться:

tab
PK Page Pole1
1   3     'a'
2   2     'b'
3   2     'c'
4   1     'a'
5   1     '123'

Как сделать это одним update'ом? Пробую что-то типа:
update (
select t1.page page1,t2.rn rn2 from tab t1,
                                                 (select rownum rn, pk from  tab
                                                           order by pk desc
                                                  ) t2
			        where t1.pk=t2.pk
				   )
set page1=ceil(rn2/2)

Падает с ошибкой "ORA-01779: cannot modify a column which maps to a non key-preserved table"

Как лучше решить эту проблему без временных таблиц и циклов?
Добрый Э - Эх
Дата: 07.11.2008 12:41:14
MERGE ?
Добрый Э - Эх
Дата: 07.11.2008 12:43:02
А вообще улыбнуло... :)
golem59
update (
select t1.page page1,t2.rn rn2 from tab t1,
                                                 (select rownum rn, pk from  tab
                                                           order by pk desc
                                                  ) t2
			        where t1.pk=t2.pk
				   )
set page1=ceil(rn2/2)
andrey_anonymous
Дата: 07.11.2008 12:43:24
golem59
Как лучше решить эту проблему без временных таблиц и циклов?

1) применить недокументированный хинт /*+ bypass_ujvc*/
2) переписать запрос в форме
update t
set Page = (select page from... where...)
WHERE pk = (select pk from... where...)
Добрый Э - Эх
Дата: 07.11.2008 12:45:57
andrey_anonymous
1) применить недокументированный хинт /*+ bypass_ujvc*/
С ним же были сложности начиная с какого-то патча ( 9.2.0.6 ??? )? Или в последних версиях патчей уже наладили
andrey_anonymous
Дата: 07.11.2008 12:47:42
Добрый Э - Эх,

Наладили
Добрый Э - Эх
Дата: 07.11.2008 12:50:59
andrey_anonymous
Добрый Э - Эх,

Наладили
Спасибо!
golem59
Дата: 07.11.2008 13:18:10
andrey_anonymous

1) применить недокументированный хинт /*+ bypass_ujvc*/
2) переписать запрос в форме
update t
set Page = (select page from... where...)
WHERE pk = (select pk from... where...)


1. c /*+ bypass_ujvc*/ вроде работает, но я так понял, что это сомнительная штука?

2. Ну вот у меня не выходит так переписать запрос.
Добрый Э - Эх
Дата: 07.11.2008 13:22:24
golem59
1. c /*+ bypass_ujvc*/ вроде работает, но я так понял, что это сомнительная штука?
Сказали же - недокументированный хинт. То есть его использование и все последствия от использования - на твой страх и риск и под твою ответственность. Если официальной техподдержки нету, то ничего страшного. Если есть, то могут отказать в помощи, в случае чего.
andrey_anonymous
Дата: 07.11.2008 13:44:16
golem59
2. Ну вот у меня не выходит так переписать запрос.

Поищите посты dmidek, он очень много раз демонстрировал такой update...
update tab t
set page = (select rn from (select rownum rn, pk
                   from (select pk from  tab  order by pk desc)) t2
                 where t2.pk = t.pk
-- В ДАННОМ случае (pk - primary key + самосоединение) where необязательно.

Еще можно на аналитике.
Типа
update (
select t.*, row_number() over(order by pk desc) rn
from tab
) set page = rn