2015-10-11 16 views
5

W tabeli mam kolumnę A i B. Chcę zaktualizować A używając wartości B, a następnie zaktualizować B do nowej wartości. To musi być zrobione atomowo.Porządek oceny wyrażenia w klauzuli-aktualizacji-zestawu w bazie danych Oracle'a

próbuję coś jak to

-- Intially A = 1, B = 2 
UPDATE T SET A = B, B = 10 WHERE ID = 1; 
-- Now A = 2, B = 10 

Choć pracuje, nie jestem w stanie znaleźć dokumentację, która gwarantuje mi, że A = B jest oceniany pierwszy i B = 10 jest oceniany później.

Spojrzałem przez oracle sql reference of the update statement

Odpowiedz

5

Można to znaleźć w standardzie SQL, który definiuje ogólne zasady.
Oracle z pewnością spełnia ten standard.

Zobacz tutaj - SQL 92: http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

strona 393, rozdział "13,9 oświadczenie < zmiana: umieszczony >", pkt 6)

6) < wartość wyrażenia > s są skutecznie ocenione przed aktualizacją - w wierszu obiektu. Jeśli a zawiera odniesienie do kolumny T, to odniesienie jest do wartości tej kolumny w wierszu obiektu, zanim zostanie zaktualizowana jakakolwiek wartość wiersza obiektu o .


Rozważmy ogólną składnię aktualizacji: <

UPDATE .... 
    SET <object column 1> = <value expression 1>, 
     <object column 2> = <value expression 2>, 
     ...... 
     <object column N> = <value expression N>; 


Zasada # 6 mówi, że wszystkie wyrażenia po prawej stronie są oceniane po pierwsze, przed aktualizacją każdej kolumny w wierszu.
Tylko wartości starego wiersza (przed aktualizacją) są uwzględniane podczas oceniania wszystkich wyrażeń.

+0

Jestem prawie pewien, że ta odpowiedź jest poprawna, chociaż chciałbym zobaczyć odniesienie w dokumentacji Oracle o tym (nawet jeden stwierdzający, że implementuje semantykę ANSI na 'update'). –

+1

W tym dokumencie: http://docs.oracle.com/cd/E11882_01/server.112/e41084/ap_standard_sql003.htm#SQLRF55516 Oracle gwarantuje, że ich RDBMS zapewnia pełną zgodność z 'E121-06, pozycjonowanym oświadczeniem UPDATE' z Standard SQL 2008. – krokodilko

1

IMO, Oracle jak innych RDBMS w pierwszej puli dane w pamięci podręcznej z tabeli, a następnie odczytać z tej pamięci podręcznej informacji, więc myślę, że w przypadku korzystania z nazwy pola w lewo po stronie SET, RDMBS odczytuje wartość twoich starych danych (przed jakąkolwiek zmianą).

+2

Oracle (i większość innych DBMS) nie zablokuje * tabeli * dla aktualizacji pojedynczego wiersza. –

1

W RDBMS (w przeciwieństwie do języka programowania) nie ma kolejności oceny, wszystko odbywa się od razu. To jak ustawić zmienne do poprzedniej wartości, a następnie wykorzystać te zmienne:

SET a=b, b=a 

Wyłączniki prostu a i b.

Ostrzeżenie: Tylko MySQL robi to całkowicie błędne, wynikające zarówno ustawione na tę samą wartość b, tutaj będziesz musiał zmiennej temp jak:

SET temp=b, b=a, a = temp 
+1

Nie robi się "od razu". Najpierw ocenia się prawą stronę, a następnie dokonuje się rzeczywista zmiana (która rzeczywiście może być postrzegana jako "wszystko na raz"). –

0

standardem SQL nie gwarantuje żadnego porządku w aktualizacji komunikat. Proponuję uruchomić dwie aktualizacje w żądanej kolejności, aby upewnić się, że są we właściwej kolejności.

-- Intially A = 1, B = 2 
BEGIN TRANSACTION; 
UPDATE T SET A = B WHERE ID = 1; 
UPDATE T SET B = 10 WHERE ID = 1; 
COMMIT TRANSACTION; 
-- Now A = 2, B = 10 
+3

To nieprawda. Standard SQL jasno określa, w jaki sposób ocenia się lewą i prawą stronę –