logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Rozwiązano] Baza danych Paradox - czy da się w Delphi dodać jednocześnie dużą ilość rekordów

leburaque 10 Lip 2018 18:47 1212 15
REKLAMA
  • #1 17321919
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    Czy ktoś może wie (lub pamięta) jak z komponentów Delphi poskładać coś co pozwala na dodanie dużej ilości rekordów (z pliku, stringa, etc) do gotowej (stacjonarnej, na dysku) bazy danych?

    Baza danych ma gotową przewidywalną strukturę i prawidłowo wyświetla mi się w komponencie TDBGrid, ale nie chcę jej edytować ręcznie, tylko wstawić tam gotowe rekordy. Może jest jakaś funkcja która dodaje rekord z danymi, albo jakoś można wywalić zawartość tabeli do stringa i parsować, albo jakakolwiek metoda bezpośredniego dodawania pól?

    Mam bazę programu do fakturowania i potrzebuję zaimportować tam z KPiR dane. Nawiązuję tym samym do posta https://www.elektroda.pl/rtvforum/topic3383101-30.html#17319214

    Większość kodu dostępnego w sieci się albo nie kompiluje w ogóle, albo jest zapomniana, albo nie ma żadnych źródeł - rozumiem, że Paradox może być nieco zapomnianą technologią.

    Dziękuję za informację.
  • REKLAMA
  • Pomocny post
    #2 17321998
    Dotnetvb
    Poziom 18  
    Posty: 309
    Pomógł: 23
    Ocena: 19
    Z tego co pamiętam paradox nie obsługuje transakcji, możesz zgłębić ten wątek może być pomocny z caschedupdates:
    http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Caching_Updates_(FireDAC)

    Jeśli potrzebujesz tylko wrzucić dane to propozycja taka: podłączenie do bazy z MS Access lub nawet Excela przez odbc driver i kopiuj wklej dane.

    Jeśli jednak ma być delphi to pętla insert rekord po rekordzie niestety będzie długo i namiętnie.
  • REKLAMA
  • #3 17322015
    AdamFilipek
    Poziom 20  
    Posty: 294
    Pomógł: 41
    Ocena: 62
    Dasz radę sam coś napisac w c#\vb\vf?
    Masz kawałek kodu, którym wyciągniesz dane - ShowTableContent i przykład jak wrzucić dane - AddNewItem

    Kod: C#
    Zaloguj się, aby zobaczyć kod


    Pętla dodania 1000 rekordów za pomocą metody AddNewItem wykonywała sie minutę i 53 sekundy.
  • #4 17322374
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    Dotnetvb napisał:
    Jeśli potrzebujesz tylko wrzucić dane to propozycja taka: podłączenie do bazy z MS Access lub nawet Excela przez odbc driver i kopiuj wklej dane.


    Pomysł jest super, w Delphi mogę sobie sparsować dane tak, żeby były gotowe do wklejenia. Ale trochę utknąłem z tym ODBC. Zainstalowałem poprawnie pakiet, następnie w Excel z zakładki Danych wybieram "z innych źródeł", następnie "z programu microsoft query / ODBC". Otwiera mi się panel "wybierz źródło danych" z którego wybieram "Paradox Files". Klikam OK, po wyskoczeniu różnych opcji typu "to źródło danych jest puste" otwiera mi się panel Microsoft Query. Tam wybieram interesujący mnie plik, dwukrotnie klikam gwiazdkę (to chyba jakiś skrót o select'a SQL) zamykam przyciskiem wyjścia. Dane zwracane są do arkusza. Wszystko działa, mogę szybko edytować ale nie wiem jak zapisać wynik edycji. Tzn. nie mam żadnej opcji zapisu z powrotem do bazy typu DB / Paradox. Jak to co edytowałem z powrotem zapisać? Podpowiesz?

    AdamFilipek napisał:
    Dasz radę sam coś napisac w c#\vb\vf?

    Niestety, są mi obce. Ale jeśli powyższy sposób (excelowy) mi się nie sprawdzi, to będę kombinował. Jak w D mogę wykodzić, to przecież komponenty są podobne (lub te same w RAD 10), więc sobie to jakoś przełożę. Póki co - spróbuję prostego rozwiązania,
  • Pomocny post
    #5 17322408
    Dotnetvb
    Poziom 18  
    Posty: 309
    Pomógł: 23
    Ocena: 19
    W Excelu rzadko korzystałem musiałbym jutro sprawdzić bo nie pamiętam albo przy połączeniu zaznaczasz połączone źródło danych albo gdzies jest opcja zapisu postaram się jutro dopisać. W Access na pewno przy tworzeniu połączenia wybierasz połączone źródło danych i każda edycja w Access jest od razu zapisywana w bazie.
  • #6 17322447
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    Dotnetvb napisał:
    W Excelu rzadko korzystałem musiałbym jutro sprawdzić bo nie pamiętam albo przy połączeniu zaznaczasz połączone źródło danych albo gdzies jest opcja zapisu postaram się jutro dopisać. W Access na pewno przy tworzeniu połączenia wybierasz połączone źródło danych i każda edycja w Access jest od razu zapisywana w bazie.


    Otworzyłem w Access i rzeczywiście mogę edytować i zapisywać informacje, ale nie jestem jakoś szczególnie z nim zaznajomiony i nie mogę rozkminić jak skopiować cały wiersz i jak potem wkleić cały wiersz / kilka wierszy (rekordów).

    Jeśli możesz mnie odesłać do jakiegoś poradnika będę wdzięczny. :)
  • Pomocny post
    #7 17322830
    Dotnetvb
    Poziom 18  
    Posty: 309
    Pomógł: 23
    Ocena: 19
    Otwórz w Access tabele do której chcesz wkleić dane, ctrl +a, ctrl+c, otwórz excel nowy arkusz ctrl+v, wytnij wszystkie wiersze oprócz nagłówków kolumn (pierwszy wiersz) , edytuj dane dodawaj, zmieniaj co chcesz, kolumnę id pozostaw pusta. Gdy skończysz zaznacz i skopiuj arkusz, w Access zaznacz ostatni wiersz w tabeli i ctrl+v, jeśli typy danych itd będą ok to Access wrzuci dane. Pamiętaj żeby jednorazowo nie wklejac dużej liczby wierszy, Access potrafi się zawiesić, myślę że tak po 5 do 10k jednorazowo będzie dobrze.
  • #8 17322978
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    Dotnetvb napisał:
    kolumnę id pozostaw pusta


    Dziękuję - to rozwiązało kwestię kopiowania / wklejania. Okazało się, że jest tam jeszcze jedno pole, które musi mieć zawartość unikatową (nie pierwsza kolumna, ale inny ID) i bez unikatowości tejże kopiowanie wywalało błędy. Czy w Access da się jakoś odszukiwać takie kolumny / zmienne które muszą mieć unikatowe wartości?

    Bardzo dziękuję! Teraz idę to jakoś oprogramować.
  • REKLAMA
  • #9 17322992
    Dotnetvb
    Poziom 18  
    Posty: 309
    Pomógł: 23
    Ocena: 19
    Kolumny oznaczone jako:
    primarry klucz główny tabeli,
    uniq wartość unikatowa w tabeli ,
    Foreign key klucz obcy czyli unikalne id z innej tabeli w relacji
  • #10 17326493
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    Dotnetvb napisał:
    Kolumny oznaczone jako:
    primarry klucz główny tabeli,
    uniq wartość unikatowa w tabeli ,
    Foreign key klucz obcy czyli unikalne id z innej tabeli w relacji


    Ostatnie pytanie - czy można edytować te wartości i np. ustawić że wartości nie są unikatowe?

    AdamFilipek napisał:
    Dasz radę sam coś napisac w c#\vb\vf?


    Nie wiem czy będzie to możliwe, ale jeśli dasz radę zerknąć w ten kod i podpowiedzieć o co kamon, będę wdzięczny.

    Utworzyłem z komponentów w Delphi 2005 (do tego mam dostęp i do niego znalazłem jakąś dokumentację odnośnie Paradox) TTable (nazwa: ParadoxTable), TDataSource (ParadoxDataSource) i TDBGrid, wszystko zbindowałem i wskazałem na poprawną bazę danych, po wykonaniu komendy
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    w TDBGrid wszystko się poprawnie wyświetla. Mogę dodać ręcznie rekord, zapisuje się i tak dalej. Kiedy próbuję to wykonać maszynowo, dostaję za każdym razem komunikat

    Key violation.
    Index: DPN_UNQ

    przy czym takiej nazwy w nagłówku tabeli po prostu nie mam (pierwszy unikalna kolumna to DPN_ID).

    Po wyciągnięciu z jakiegoś zapomnianego forum kodu, dodałem na wszelki wypadek linijkę zawierającą przydzielenie unikatowego numeru (zresztą, bez tej linijki efekt jest ten sam):

    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    W efekcie jak na załączonym obrazku dodaje się rekord, nie dodaje się numer unikatowy a wszelkie próby potwierdzenia i akceptacji tego rekordu "ręcznie" wywołują wspomniany błąd Key violation i w żaden sposób nie mogę przypisać wartości do pierwszej zmiennej / kolumny.

    Baza danych Paradox - czy da się w Delphi dodać jednocześnie dużą ilość rekordów

    Jakaś podpowiedź?
  • #11 17326689
    Dotnetvb
    Poziom 18  
    Posty: 309
    Pomógł: 23
    Ocena: 19
    aField[0] := '5'; // Tę linijkę dodałem żeby sprawdzić czy to coś zmieni (nic oczywiście nie zmieniło) - nie zmieni bo aField to nie jest tabela w bazie tylko obiekt w pamięci, do którego pobierasz dane z bazy,

    Tutaj sprawdzaj po kolei każde pole jaką ma wartość:
    if (ParadoxTable.fields[i].CanModify) then // tu próbowałem także usunąć warunek, bez skutku
    ParadoxTable.fields[i].Value := aField[i];
    end;

    ParadoxTable.fields[i].Value - to jest pole w tabeli bazy danych, któremu przypisujesz wartość, może pomijaj pole DPN_ID warunkiem, jeśli tabela ma autoincrenment w polu DPN_ID, to możesz pomijać to pole przy zapisie, baza sama je uzupełni:
    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    Nie mniej samo Delphi to dla mnie dawne czasy, myślę że ktoś bardziej w temacie na pewno pomoże
  • REKLAMA
  • #12 17327194
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    Dotnetvb napisał:
    pomijaj pole DPN_ID warunkiem


    zapomniałem o tym napisać, że spróbowałem też takiego sposobu:

    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    a także w ogóle pominięcia pierwszego field'a, z nadzieją na autouzupełnienie:

    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    i w każdym przypadku dostaję ten sam wynik.

    Ale bardzo dziękuję za odzew!
  • #13 17327228
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1464
    Dotnetvb napisał:

    Jeśli jednak ma być delphi to pętla insert rekord po rekordzie niestety będzie długo i namiętnie.


    Dinozaury pamiętają, że o ile dało się poprosić plikową bazę danych o otwarcie w trybie wyłącznym, da się ją wiele lepiej buforować. Np Clipper.
    Każda operacja (łącznie z prev-next) na plikowych w trybie dzielonym musi zakładać, że posiadane w RAM dane (i co gorsza, strony indeksów) nie są aktualne.

    Edit.
    Faktem jest, że Paradox był nieco nowocześniejszą bazą, niż dBase/Clipper (tam np w ogóle koncepcji automatycznego klucza nie było). Nie wszystko musi być tak samo.
  • #14 17327253
    AdamFilipek
    Poziom 20  
    Posty: 294
    Pomógł: 41
    Ocena: 62
    Ten kawałek kodu który wstawiałem dodawał rekordy bez wstawiania wartości do kolumny "ID" a wartość była inkrementowana i wstawiana przez bazę.
  • #15 17327825
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    W tym przypadku niestety nie mogę zmienić samej bazy danych na jakąś nowszą. :( Tak czy siak - na razie żadna z opcji nie działa, spróbuję popytać jeszcze w innych miejscach, a póki co to dodam, że a) na różne sposoby pomijam edycję tego pola (zresztą i tak nie można go w żaden sposób nadpisać, bo od razu jest break) i b) komunikat dostaję dokładnie w momencie

    Kod: Delphi
    Zaloguj się, aby zobaczyć kod


    czyli przy próbie zapisania elementu tabeli.
  • #16 17548835
    leburaque
    Poziom 17  
    Posty: 488
    Pomógł: 4
    Ocena: 111
    OK, głównym problemem jest unikatowość rekordów, bo cała reszta idzie z automatu jak burza. Jeśli jakieś pole jest ustawione na unikatowe wartości a my takich nie dodajemy, to najprawdopodobniej jest główną przyczyną problemu z dodaniem rekordu.

    Zagrzebałem się w wielu różnych miejscach i wielu różnych forach - jesli nie zna się założonej struktury bazy Paradox, to jej nieprzystępność sprowadza się do tego, że trzeba ręcznie eksperymentować. W skrócie - pola w bazie danych mogą być unikatowe - zazwyczaj można je poznać po tym, że w edytorze albo podglądzie poprzez Excel-Access kolejne rekordy mają pola unikatowe; czasem warunek może dotyczyć dwóch i więcej pól na raz, a więc ogarnięcie czy dany rekord w danym miejscu pozwoli na unikatowość czy nie - jest czasem trudne i tym trudniejsze im baza danych jest większa.

    Nie udało mi się znaleźć jakiejś spójnej metody wyciągania z bazy informacji co i w jaki sposób ma być unikatowe; praca na starej bazie danych to metoda prób i błędów; u mnie po prostu sprawdzałem dodając najpierw wszystkie unikatowe wartości, a następnie różne kombinacje tego co można powtórzyć a co nie. Straszna robota. ;)

    Przydaje się oczywiście fragment kodu
    if (ParadoxTable.fields[i].CanModify) then
    ParadoxTable.fields[i].Value := aField[i];
    bo pomija od razu wartości które są autoinkrementowane i sam przydziela te wartości, niemniej sprawa jest nadal bez jednego rozwiązania. Temat zamykam, bo chyba nic więcej nie ma do dodania, bardzo dziękuję Panowie za pomoc, mi się udało zbudować to czego potrzebowałem. Jakby ktoś potrzebował, to spróbuję się podzielić doświadczeniem.

    Pozdrawiam!

Podsumowanie tematu

LABEL_AI_GENERATED
W dyskusji poruszono problem dodawania dużej ilości rekordów do bazy danych Paradox za pomocą Delphi. Użytkownik szukał sposobu na automatyczne wstawianie danych z pliku lub stringa do istniejącej bazy, która ma ustaloną strukturę. Odpowiedzi sugerowały różne metody, w tym użycie ODBC do połączenia z bazą danych przez MS Access lub Excel, co umożliwia łatwe kopiowanie i wklejanie danych. Wskazano również na problemy z unikalnością rekordów, które mogą powodować błędy przy próbie dodawania danych. Użytkownik próbował różnych podejść w Delphi, w tym pomijania pól unikalnych, ale napotykał na komunikaty o naruszeniu klucza. Wskazano, że kluczowe jest zrozumienie struktury bazy danych Paradox oraz unikalnych wymagań dotyczących pól.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA