Você deve ser capaz de fazer isso com uma subconsulta correlacionada
UPDATE tbl1 t1
SET t1.b = (SELECT c
FROM tbl2 t2
WHERE t1.id = t2.id
AND t1.a = t2.a
AND t1.b = t2.b
AND t2.d = 'a')
WHERE t1.a = 'foo'
AND EXISTS( SELECT 1
FROM tbl2 t2
WHERE t1.id = t2.id
AND t1.a = t2.a
AND t1.b = t2.b
AND t2.d = 'a')
O problema com o
UPDATE
que você escreveu é que a Oracle não pode garantir que haja exatamente 1 tbl2.c
valor que corresponde a um único tbl1.b
valor. Se houver várias linhas em tbl2
para qualquer linha específica em tbl1
, a atualização correlacionada lançará um erro indicando que uma subconsulta de uma única linha retornou várias linhas. Nesse caso, você precisaria adicionar alguma lógica à subconsulta para especificar qual linha de tbl2
para usar nesse caso.