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źć?
@mikra25: update zaliczenie set ocena=3, zaliczenie.data=current_date where zaliczenie.PK in (SELECT zaliczenie.PK FROM przedmiot, zaliczenie WHERE przedmiot.id_przed=zaliczenie.id_przed AND przedmiot.nazwa='Fizyka' AND zaliczenie.ocena=2) Za PK wstaw klucz główny tabeli zaleczenie
@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
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 SET z.ocena=3, z.data = SYSDATE WHERE z.id_przed IN ( SELECT id_przed FROM przedmiot WHERE nazwa = "Fizyka" ) AND z.ocena = 2; Rozumiem, że chcesz zaktualizować w tabeli zaliczenie oceny dla
@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.
@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.
@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.
@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.:)
@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 IN (SELECT przedmiot.idprzed FROM przedmiot WHERE przedmiot.nazwa = 'Fizyka') AND zaliczenie.ocena = 2
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źć?
update zaliczenie
set ocena=3, zaliczenie.data=current_date
where zaliczenie.PK in
(SELECT zaliczenie.PK
FROM przedmiot, zaliczenie
WHERE przedmiot.id_przed=zaliczenie.id_przed
AND przedmiot.nazwa='Fizyka'
AND zaliczenie.ocena=2)
Za PK wstaw klucz główny tabeli zaleczenie
id_przed NUMBER(3,0),
nr_albumu NUMBER(3,0),
termin VARCHAR2(15),
data DATE,
ocena NUMBER(1),
CONSTRAINT zaliczenie_01 PRIMARY KEY (id_przed,nr_albumu,termin),
CONSTRAINT zaliczenie_02 FOREIGN KEY (nr_albumu) REFERENCES student (nr_albumu),
CONSTRAINT zaliczenie_03 FOREIGN KEY (id_przed) REFERENCES przedmiot (id_przed),
CONSTRAINT zaliczenie_04 CHECK (ocena IN (2,3,4,5)),
CONSTRAINT zaliczenie_05 CHECK (termin IN ('1','2','3','KOMIS'))
Poprawna kolejność powinna być jak wyżej:
UPDATE SET FROM WHERE AND AND
Na pewno początek powinien być taki:
UPDATE zaliczenie z
SET z.ocena=3, z.data = SYSDATE
i tutaj nie do końca ogarniam, ale domyślam się że coś takiego
WHERE z.idprzed IN
(
SELECT idprzed FROM przedmiot WHERE nazwa = 'Fizyka'
)
AND z.ocena = 2;
Ogólnie, to poczytaj jak
W Oracle w UPDATE nie masz w ogóle FROM
Składnia jest taka
UPDATE [tabela]
SET [wartości, które zmieniasz]
WHERE [warunki]
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
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
SET z.ocena=3, z.data = SYSDATE
WHERE z.id_przed IN
(
SELECT id_przed FROM przedmiot WHERE nazwa = "Fizyka"
)
AND z.ocena = 2;
Rozumiem, że chcesz zaktualizować w tabeli zaliczenie oceny dla
@oko_strusia: (+) to najgorsze co może być.. w ogóle nie widać kiedy left idzie... ;s
Jak coś to pisz, ale doczytaj o składni :)
Warunki, według których wybierasz są zależne od innych tabel.:)
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 IN (SELECT przedmiot.idprzed
FROM przedmiot
WHERE przedmiot.nazwa = 'Fizyka')
AND zaliczenie.ocena = 2