ORACLE SQL: коррелированная проблема обновления
Привет, ребята, у меня есть такого рода проблемы, связанные с обновлением на Oracle.
посмотрим, у меня есть таблица параметров.
id_s id_p value desc
-----------------------------------------------
10064 9 aaa r
10064 8 bbb t
10064 4 ccc t
10064 4 ttt y
11119 9 ddd f
11119 8 eee g
11119 4 fff b
11119 4 kkk x
поэтому я хочу обновить параметры, чтобы получить следующее
id_s id_p value desc
-----------------------------------------------
10064 9 aaa r
10064 8 bbb t
10064 4 ccc t
10064 4 ttt y
11119 9 aaa r
11119 8 bbb t
11119 4 ccc t
11119 4 ttt y
я пишу обновление, как это
update params p1
set (p1.value, p1.desc) = (
select p2.value
, p2.desc
from params p2
where p2.id_s = 10064
and p2.id_p = p1.id_p
)
where p1.id_s = 11119
;
выполнение возвращает ошибку "ORA01427: однострочный подзапрос возвращает более одной строки"
Как я могу сделать это обновление работает?
2 ответа
Вы должны добавить дополнительное условие к вашему подзапросу:
update params p1
set (p1.value, p1.desc) = (
select p2.value
, p2.desc
from params p2
where p2.id_s = 10064
and p2.id_p = p1.id_p
and p1.id_s = 11119
)
where p1.id_s = 11119
;
edit: вопросы еще более усложняются обновлением спецификации операции, которое фактически сводится к частичному обновлению pk (поскольку приведенные выдержки из таблицы являются полными по столбцам).
возможное решение реализует следующую основную идею: набор результатов для мастер-комбинации id_p
, id_s
в сочетании с результирующим набором для ведомой комбинации тех же столбцов в соответствии с рангом в 2 порядках. упорядочения - это просто упорядочения результирующего набора в соответствии со столбцами value
а также desc
, но, конечно, любой другой будет делать то же самое (обратите внимание, что, в частности, 2 различных заказа были возможны).
указанное сопряжение затем коррелируется с набором результатов обновления.
в оракуле sql:
update params p1
set (p1.value, p1.desc) = (
select emb.value
, emb.desc
from (
select p2.value
, p2.desc
, p2.id_p
, rownum rn
from params p2
where p2.id_s = 10064
order by p2.value
, p2.desc
) emb
join (
select pm.value
, pm.desc
, pm.id_p
, rownum rn
from params pm
where pm.id_s = 11119
order by pm.value
, pm.desc
) emb_master
ON ( emb_master.id_p = emb.id_p
AND emb_master.rn = emb.rn )
where p1.id_s = 11119
and emb_master.id_p = p1.id_p
and emb_master.value = p1.value
and emb_master.desc = p1.desc
)
where p1.id_s = 11119
;
Жизнеспособность этой схемы зависит от предположения, что результирующие наборы по модулю каждого значения кортежа (id_p
, id_s
) иметь одинаковую кардинальность. если нет, обновления будут неполными.
проверено на ora 11g2 на основании приведенных выдержек.
Вы не указываете, что делать, если возвращено более одной строки. Вы можете просто выбрать произвольную строку, используя rownum = 1
:
update params p1
set (p1.value, p1.desc) = (
select p2.value, p2.desc
from params p2
where p2.id_s = 10064 and p2.id_p = p1.id_p and rownum = 1
)
where p1.id_s = 11119;