znaczacy > comp.* > comp.bazy-danych.msaccess

PASQUALE (15.06.2004, 13:11)
Szanowni Grupowicze,

chce zupdate'owac tylko jeden dowolny rekord w tabeli, nie wszystkie. Moze
to byc pierwszy, ostatni, dowolny, ale tylko jeden.
Nie mam jednak zadnego pola ID ani takiego, ktore zawieraloby unikalne dane.
Niby proscizna, ale ni cholery nie wiem jak to zrobic.

pozdrawiam i dzieki z gory
Rafal Posmyk (15.06.2004, 13:25)
PASQUALE wrote:

> chce zupdate'owac tylko jeden dowolny rekord w tabeli, nie wszystkie. Moze
> to byc pierwszy, ostatni, dowolny, ale tylko jeden.
> Nie mam jednak zadnego pola ID ani takiego, ktore zawieraloby unikalne
> dane.


Zatem musisz podac wystarczajaco duzo warunkow w klauzuli
WHERE, aby trafic dokladnie _ten jeden_ rekord. W klauzuli
WHERE mozesz takze uzywac pol, ktore nie sa polami kluczy
ani tez nie sa dla nich zdefiniowane unikalne indeksy.
W najgorszym wypadku bedziesz musial w klauzuli WHERE
uwzglednic wszystkie pola tabeli. Choc nawet wtedy bedzie
mozliwe trafienie kilku rekordow.

Ciao, Smyk
PASQUALE (15.06.2004, 13:35)
W miedzyczasie przyszla mi do glowy taka mysl:

UPDATE tbl_GotoweDane
SET MojaTabela.MojePole = 'Moja nowa wartoœć'
WHERE MojaTabela.MojePole In (select max(MojePole) from MojaTabela);

Czy cos takiego moze poprawnie zadzialac?
[..]
Grzegorz Danowski (15.06.2004, 14:15)
"PASQUALE" <pasquale> wrote in message
news:fpj1
> W miedzyczasie przyszla mi do glowy taka mysl:
> UPDATE tbl_GotoweDane
> SET MojaTabela.MojePole = 'Moja nowa wartoœć'
> WHERE MojaTabela.MojePole In (select max(MojePole) from MojaTabela);
> Czy cos takiego moze poprawnie zadzialac? (...)


Zadziała, ewentualnie możesz spróbować też z Exists - czasami bywa szybsze
(ale załóż indeks na pole MojePole). Oczywiście jeśli pole MojePole nie jest
unikalne i dla wartości maksymalnej jest więcej rekordów, to ta kwerenda
zaktualizuje je wszystkie a nie tylko jeden.
G.

Ps. Czemu nie ma klucza głównego w tej tabeli - jest to raczej niezgodne ze
sztuką?
RAdek (15.06.2004, 14:16)
CZeść

Dnia 15 czerwca 2004 w pewnym liście napisane było:

> W miedzyczasie przyszla mi do glowy taka mysl:


> UPDATE tbl_GotoweDane
> SET MojaTabela.MojePole = 'Moja nowa wartość'
> WHERE MojaTabela.MojePole In (select max(MojePole) from MojaTabela);


Pod warunkiem, że MojePole jest unikalne.
Czy to musi być update z SQL'a? Bo można to załatwić recordsetem.
Krzysztof Wiśniewski (15.06.2004, 14:52)
PASQUALE wrote:
> W miedzyczasie przyszla mi do glowy taka mysl:
> UPDATE tbl_GotoweDane
> SET MojaTabela.MojePole = 'Moja nowa warto?ć'
> WHERE MojaTabela.MojePole In (select max(MojePole) from MojaTabela);
> Czy cos takiego moze poprawnie zadzialac?


Czy naprawdę nie prościej będzie dodać unikalny identyfikator do tabeli?

Albo, skoro masz sposób na znalezienie tego rekordu, to dlaczego nie
użyć recordsetu?

Set rst = CurrentDB.OpenRecordset("SELECT MAX(MojePole) FROM MojaTabela")
with rst
if .EOF And .BOF Then
Exit sub
MsgBox ("Nic tu nie ma!")
End if
.MoveFirst
.Edit
...
.Update
.Close
end With
Set rst = Nothing

Pozdrawiam,
Krzysiek
Grzegorz Danowski (15.06.2004, 15:50)
"Krzysztof Wiśniewski" <ktuvok> wrote in message
news:0609
[..]
> .Close
> end With
> Set rst = Nothing


Dlaczego? Czy przez rekordset będzie krócej (mniej kodu)? Albo szybciej? No
i jak na to wpadłeś, że ten rekordset da się edytować (Select
Max(MojePole)...)? :-)

Pozdrawiam
Grzegorz
PASQUALE (15.06.2004, 16:24)
> Ps. Czemu nie ma klucza głównego w tej tabeli - jest to raczej niezgodne ze
> sztuką?


Dlatego, ze to wyszlo dopiero jak juz byla gotowa cala aplikacja, a tabela
ta sluzy do zaimportowania pliku tekstowego "tak jak jest" w celu dalszej
obrobki. W takich przypadkach nigdy nie zakladam kluczy unikalnych, bo do
tej pory nie mialem takiej potrzeby.
PASQUALE (15.06.2004, 16:27)
> > UPDATE tbl_GotoweDane
> > SET MojaTabela.MojePole = 'Moja nowa wartoœć'
> > WHERE MojaTabela.MojePole In (select max(MojePole) from MojaTabela);

> Zadziała, ewentualnie możesz spróbować też z Exists - czasami bywa szybsze
> (ale załóż indeks na pole MojePole). Oczywiście jeśli pole MojePole nie jest
> unikalne i dla wartości maksymalnej jest więcej rekordów, to ta kwerenda
> zaktualizuje je wszystkie a nie tylko jeden.


Spytam, tak jeszcze dla pewnosci: Czy konstrukcja

SELECT * FROM MojaTabela
WHERE MojePole In (select max(MojePole) from MojaTabela);

oby na pewno zwroci zawsze tylko jeden jedyny rekord?
Krzysztof Wiśniewski (15.06.2004, 16:36)
Grzegorz Danowski wrote:
> Dlaczego? Czy przez rekordset będzie krócej (mniej kodu)?


nie.

> Albo szybciej?


też nie :)

Ale czasem metoda "brutalnego dochodzenia do wyniku" działa.

> No i jak na to wpadłeś, że ten rekordset da się edytować (Select
> Max(MojePole)...)? :-)


Taaa, chyba rzeczywiście przesadziłem, ale można tę kwerendę zapisać
inaczej (może mniej wydajnie, ale co mi tam), np.
"SELECT MojePole FROM Tabela ORDER BY MojePole DESC LIMIT 1"
- czy teraz zadziała?

Pozdrawiam,
Krzysiek
RAdek (15.06.2004, 16:39)
CZeść

Dnia 15 czerwca 2004 w pewnym liście napisane było:

> Spytam, tak jeszcze dla pewnosci: Czy konstrukcja


> SELECT * FROM MojaTabela
> WHERE MojePole In (select max(MojePole) from MojaTabela);


> oby na pewno zwroci zawsze tylko jeden jedyny rekord?


Odpowiem raz jeszcze:
Pod warunkiem, że MojePole jest unikalne, a dokładniej: Max(MojePole).

Możesz zresztą wyrzucić "In". Wtedy w przypadku, gdy będzie to więcej
niż jeden rekord to wystąpi błąd.
RAdek (15.06.2004, 17:05)
CZeść

Dnia 15 czerwca 2004 w pewnym liście napisane było:

>> Set rst = CurrentDB.OpenRecordset("SELECT MAX(MojePole) FROM MojaTabela")


Aleście się uparli na te maxy. Nie prościej zrobić:
Set rst = CurrentDB.OpenRecordset("SELECT * FROM MojaTabela")


Przecie w takim przypadku nie pociągnie całej tabeli, tylko 1 rekord.
Będzie szybko i sprawnie.

BTW. Czy ktoś pamięta, czemu zalecane było sprawdzanie .EOF i .BOF
zamiast samego .EOF?
Krzysztof Wiśniewski (15.06.2004, 17:08)
RAdek wrote:
> CZeść
> Dnia 15 czerwca 2004 w pewnym liście napisane było:
>>>Set rst = CurrentDB.OpenRecordset("SELECT MAX(MojePole) FROM MojaTabela")

> Aleście się uparli na te maxy. Nie prościej zrobić:
> Set rst = CurrentDB.OpenRecordset("SELECT * FROM MojaTabela")


Prościej, ale nie bardzo rozumiem, dlaczego chcesz wybierać wszystkie
rekordy... MAX miał (zapewne) zawęzić obszar poszukiwań do jednego
wiersza / rekordu.

Pozdrawiam,
Krzysiek
RAdek (15.06.2004, 17:15)
CZeść

Dnia 15 czerwca 2004 w pewnym liście napisane było:

> Prościej, ale nie bardzo rozumiem, dlaczego chcesz wybierać wszystkie
> rekordy... MAX miał (zapewne) zawęzić obszar poszukiwań do jednego
> wiersza / rekordu.


Bo obliczenie Max'a zajmie więcej czasu niż zrobienie MoveFirst.
Szczególnie, że pola są nieindexowane. A efekt będzie ten sam, tzn.
zostanie wybrany jeden rekord do edycji (choć w obu przypadkach pewnie
inny).
Grzegorz Danowski (15.06.2004, 17:37)
"RAdek" <radeks> wrote in message
news:1518
> CZeść
> Dnia 15 czerwca 2004 w pewnym liście napisane było:
> Bo obliczenie Max'a zajmie więcej czasu niż zrobienie MoveFirst.
> Szczególnie, że pola są nieindexowane. A efekt będzie ten sam, tzn.
> zostanie wybrany jeden rekord do edycji (choć w obu przypadkach pewnie
> inny).


A więc zatem to, że inny, to już nie ma znaczenia? :-)
Grzegorz

Podobne wątki