Imagine a seguinte tabela:
id | nome | família ---+------+-------- 0 | João | ferreiro 1 | Maria | invernos 2 | João | Corça
e agora a seguinte afirmação:
UPDATE t SET name = 'John' WHERE id = 0;
Na verdade, essa declaração não atualizaria nada – pois reflete o que já existe. Agora todos os blogs, manuais e whatsnots disseram para verificar SQL%ROWCOUNT
o número de linhas atualizadas. Fazer isso retorna 1
( linhas afetadasWHERE
– ou seja, aquelas com as quais a cláusula correspondeu). Vamos a outro:
UPDATE t SET family = 'Smith' WHERE name = 'John';
De fato, isso só mudaria a linha com id=2, então eu quero algo informando "1 linha atualizada" - mas SQL%ROWCOUNT
nos dá 2
(novamente, linhas afetadas ).
Então aqui vem a pergunta final: O que dá o número de linhas alteradas ?
Se você emitir uma instrução de atualização em sua tabela que atualize efetivamente os dados para o mesmo valor que já está lá, o banco de dados atualiza a linha, portanto,
SQL%ROWCOUNT
é preciso, mesmo que o novo valor seja o mesmo que o valor antigo.Você pode usar uma consulta de versões de flashback para ver se o banco de dados realmente atualizou o registro:
Na primeira consulta acima, provavelmente haverá apenas uma linha retornada para
ID=0
. Então, depois de emitir e confirmar uma atualizaçãoID=0
na segunda vez que a consulta de versões de flashback for executada, você deverá recuperar dois registros, um para o registro original onde aVERSIONS_ENDTIME
coluna foi preenchida e outro para a nova versão do registro mostrando que a operação contra foi umU
pdate e que o registro tem umVERSIONS_STARTTIME
horário igual ao final do registro original.A única maneira de impedir que os registros sejam atualizados com os mesmos valores é com um predicado apropriado na cláusula where ou em uma atualização on para cada gatilho de linha que rejeita a alteração gerando um erro.