Wpis z mikrobloga

#programowanie #oracle #sql

Chce napisać zapytanie które dokona edycji wartości w jednej tabeli na podstawie wartości w drugiej. Ma to wyglądać w ten sposób, że chce zmienić ocenę w tabeli zaliczenia na podstawie nazwy przedmiotu z tabeli przedmioty (w zaliczeniach jest klucz obcy na id przedmiotu). Próbuję to zrobić w ten sposób:

UPDATE (SELECT przedmiot.nazwa, zaliczenie.ocena
FROM przedmiot, zaliczenie
WHERE przedmiot.id_przed=zaliczenie.id_przed
AND przedmiot.nazwa='Fizyka'
AND zaliczenie.ocena=2)
SET ocena=3, zaliczenie.data=(SELECT sysdate FROM dual);

ale dostaje SQL Error: ORA-00904. Mam pewności, że nazwy tabeli itp są poprawne. Może ktoś pomóc to rozgryźć?
  • 19
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@oko_strusia: Właśnie chciałem kombinować w ten sposób tylko, że tabela zaliczenia jest zbudowana w specyficzny sposób, tak jakby bez klucza głównego

id_przed NUMBER(3,0),
nr_albumu NUMBER(3,0),
termin VARCHAR2(15),
  • Odpowiedz
@mikra25: Na dzień dobry masz złą składnie, więc się wywali...
Poprawna kolejność powinna być jak wyżej:
UPDATE SET FROM WHERE AND AND

Na pewno początek powinien być taki:
UPDATE
  • Odpowiedz
@mikra25: Własnie doczytałem jeszcze
W Oracle w UPDATE nie masz w ogóle FROM

Składnia jest taka
UPDATE [tabela]
SET [wartości, które zmieniasz]
WHERE [warunki]
  • Odpowiedz
@mpisz: Robiłem tak na początku to mi się rzucał że nazwa tabeli przedmiot jest niepoprawna lub tabela nie istnieje. Myślałem to zrobić po prostu
UPDATE zaliczenie
SET ocena=3
WHERE zaliczenie.idprzed=przedmiot.idprzed
AND przedmiot.nazwa='Fizyka'
i wydaje mi się że to powinno działać ale nie działa
  • Odpowiedz
To Ci nie może zadziałać, bo nie podajesz nigdzie pobrania z tabeli przedmiot.
Ten update co dałem wyżej nie działa? Jak ORA sypie?

Bo jak masz wszystko ok, to to na 100% powinno zadziałać (mogłem nazwy kolumn pozmieniać)

UPDATE zaliczenie z
  • Odpowiedz
@oko_strusia: Nie rób złączeń w ten sposób. W tym przypadku najpierw wykonuje się FROM i robi wielki iloczyn kartezjański a potem dopiero WHERE go filtruje. Jak podasz we FROM tylko tabelę nadrzędną i dodasz JOIN XXX ON A=B to tego unikniesz.
  • Odpowiedz
@SpioncyPotwur: Z tego co mi wiadomo to optymalizator przebuduje to i tak na taką składnię, żeby kartezjana nie robić. Ale ogólnie uwaga względnie słuszna. Nie wiem jak w innych DMBS. W Oraclu możesz sobie zobaczc plan zapytania jednego i drugiego zapytania i powinny być takie same.
  • Odpowiedz
@oko_strusia: Prawda, ale po pierwsze - poleganie na automatycznych optymalizacjach nie do końca jest ok a po drugie o ile Oracle jest w optymalizacjach świetny to przenosząc kod na inny system, nie możemy mieć pewności, że to będzie działać tak samo.
  • Odpowiedz
@mikra25: Update opiera się na jednej tabeli, bo aktualizujesz dane tylko w tabeli zaliczenie.
Warunki, według których wybierasz są zależne od innych tabel.:)
  • Odpowiedz
@mikra25: 1) alias "zaliczenie" nie sięga poza nawias
2) próbujesz zrobić "update z selekta". Oracle od wersji 11 dopuszcza takie rzeczy ale jeśli select jest z 1 tabeli. Nie używać
3) przepisz to aby zrobić samą instrukcję update a nie update z selecta, np:
UPDATE zaliczenie
SET ocena = 3, data = SYSDATE
WHERE zaliczenie.idprzed
  • Odpowiedz