Wątek przeniesiony 2015-10-01 16:05 z Newbie przez furious programming.

Czy istnieje jakieś dodatkowe zabezpieczenie w ADO przed edycją danych z grida?

0

Witajcie,

Pytanie dość nietypowe. W DataSource ustawiam dwa różne DataSety. Pierwszy to DataSet -> ADOQuery który łączy się do bazy mdb (testowej oczywiście). Po tej operacji istnieje możliwość edycji danych z grida. Wszystko pięknie ładnie działa tak jak chce. W drugim DataSet podpinany jest obiekt klasy:

strict private
        FDS: TDataSet;

który otwierany jest nieco inaczej niż zwykły ADOQuery z formy (czyt.

connection.connect; query.open;

)
otóż przekazywany i zwracany jest jako parametr typu var do odpowiedniego interfejsu. Niby w interfejsie do połączenia też jest ADO jednak wglądu w to nie mam i jako parametr var zwrotnie dostaje otwarte FDS:

db.Get(ConnectionId).Open(sql.Text, sql.ParamsIn, nil, FDS);

to powoduje, że dane w DBGrid się pojawiają. Ustawiając

FDS.Edit;

niby możliwa jest edycja pól w gridzie (nawet dla pola z datą otwiera się TDateTimePicker) ale po wybraniu daty, wpisaniu czegoś z palca czy cokolwiek innego dane się nie zapisują mimo iż FDS.State = dsEdit;

. W związku z powyższym pytanie do was jaka jest przyczyna tego, że dane się nie wpisują do DataSet (nie mówię o commicie na bazie bo to inny temat ale o samo wpisane danych do FDS). Czy może w komponencie typu Connection istnieje jakiś mechanizm blokujący? 
PS. 
```delphi
TDataSource.AutoEdit = True;

PS2. Jak podpiąłem DBNavigatora i próbowałem zrobić Delete rekordu to dostałem komunikat:

Za mało informacji o tabeli bazowej do aktualizacji lub odświeżenia

PS3.
Zapomniałem jeszcze dodać, że w przypadku pierwszego dataseta użyty jest lokalny z formatki komponent i query podpięte pod bazę danych mdb gdzie normalnie jest

select * from tabela

natomiast w drugim przypadku jest to MSSQL i dane zwrócone są poprzez

EXEC [dbo].[sp_NazwaProcedury] :Param1, :Param2, :Param3

Może to jest przyczyna?

0

jak sobie wyobrażasz automatyczne wygenerowanie polecenia UPDATE z polecenia EXEC [dbo].[sp_NazwaProcedury] :Param1, :Param2, :Param3 ???

0

@abrakadaber nie chodzi o zapisanie danych w bazie tylko w samym datasecie bez jakichkolwiek operacji na bazie danych. Asekuracyjnie zmieniłem też ten

EXEC 

na SELECT

i też nie działa. Wygląda to tak jakby sam komponent CONNECTION był ustawiony w trybie read only.
0

@woolfik czy ja dobrze rozumiem? W MSSQL masz procedurę i jej wynik chcesz aktualizować? Jeśli tak, to nie wiem czy tak się da.

0

@Mr.YaHooo ... nie chodzi o aktualizację bazy danych tylko o zmianę danych w samym dataset. Jak pisałem wyżej zmiana EXEC na SELECT też nic nie dała bo dalej nie mogę zmieniać danych w TDataSet z poziomu grida.

1

żeby edycja w gridzie działała to w najprostszej postaci musisz mieć w query select z jednej tabeli - nie z procedury, widoku czy czego tam jeszcze.
tu masz jak to zrobić jeśli w query masz coś innego http://stackoverflow.com/questions/11691766/how-do-you-delete-update-etc-tables-produced-by-queries-in-delphi-ado. Po prostu ADO nie potrafi samo (i wcale mu się nie dziwię) wygenerować sobie odpowiedniego zapytania dla update czy delete

EDIT:
Przeczytałem kolejne posty i się pogubiłem - co w końcu chcesz zrobić? Bo jak dasz delete czy edit i potem post to to OD RAZU leci do bazy. Jak chcesz dane zmieniać bez zapisywania to musisz je z query do jakiegoś memtable przerzucić i dopiero ten memtable podpiąć pod grida i w nim zmieniać

W nowszych delphi masz FDMemTable, w starszych darmowey kbMemTable, jest też jeszcze ClientDataSet

1

@woolfik to musisz użyć komponentu typu TClientDataSet. Wtedy możesz edytować rekordy po stronie klienta i nie odsyłać zmian do bazy danych (bazy danych też w ogóle może nie być, albo może być tylko na starcie programu aby wczytać dane, potem można się rozłączyć). Inaczej mi się wydaje, że się nie da.

Akurat o tym kolega napisał w edycji sekundkę wcześniej niż ja ;)

0

@abrakadaber i @Mr.YaHooo zrobiłem jak pisaliście mam nawet oddzielny TADOConnection (połączony) TADOQuery (aktywowane) TDataSetProvider (spięty z TADOQuery) i TClientDataSet (spięty z TDataSetProvider) oraz TDataSource (którego DataSet wskazuje na TClientDataSet) straszne ale ok widzę rekordy na gridzie i ... dalej nie idzie zmieniać.

0

Panowie mieliście racje. W przypadku wielojoinowych zapytań ADO sobie z tym nie radzi (do teraz pracowałem na UniDAC i ZeosLib i tam takich problemów nie ma). Jak użyłem tego ClientDataSeta tak jak @abrakadaber podał problem się rozwiązał. Co prawda rzeźby jest w choinkę więcej ale działa :)

0

Czyli tak naprawdę ADO słabe jest. Bo bardzo często pisze się wielojoinowe zapytania. Raczej mało kiedy mam taką sytuację, że dane siedzą wprost i nic więcej nie potrzeba.

A TClientDataSet jest moim zdaniem dość ciężki w użyciu ;)

0

Kiepskie kiepskie ale tak jak pisałem na początku aplikacja zbudowana jest z wielu różnych bpl pisanych przez różnych programistów. Gość, który dostał do zrobienia interfejs obsługujący komunikację z bazą danych użył właśnie ADO i teraz żeby to przerobić to by trzeba z pół roku pracy w to włożyć a na to jak to zwykle bywa nie ma czasu więc siedzę i rzeźbię :)

0

To faktycznie się nie ma co bawić. Chyba, że zdecydujecie się na przepisanie tego od zera ze zmianą architektury.

Swoją drogą nie tylko ADO ma bugi. Z wielojoinowymi zapytaniami średnio sobie radzi edytor TIBDataSet. Zdarzyło mi się, że nie umiał wygenerować poprawnie zapytań insert czy update jeśli w zapytaniu miałem różne joiny. Nie mówię już o złym generowaniu zapytania refresh które kuleje nawet przy najprostszym złączeniu :/

1 użytkowników online, w tym zalogowanych: 0, gości: 1