INSERT do bazy PostgreSQL z tablicy zagnieżdżonej

0

Witam, posiadam tablicę w takiej postaci (przykład):

 T_zbior_1_1_1 = packed record
   pole5:byte;
   pole6 : byte;
   pole7: byte;
 end;

 T_zbior_1_1 = packed record
   pole3:byte;
   pole4 : byte;
   zbior2: T_zbior_1_1_1 ;
 end;

T_zbior_1 = packed record
   pole1 : word;
   pole2     : byte;
   zbior1     : T_zbior_1_1;
 end;

I mam tablicę zawierająca X takich rekordów jak wyżej, czyli:

ArrayPodst : array of T_zbior_1;

Mam też bazę danych w PostgreSQL o znanej mi strukturze.
Pytanie, czy jest jakiś sprytny sposób na to, żeby zrobić w ramach jednej transakcji (WSZYSTKO albo NIC [w przypadku bledu])? Jest jakieś narzędzie pozwalające zrobić kod SQL INSERT z takiej ArrayPodst? Jeśli nie, to jak to zrobić na piechotę, ale w miarę "gentle"?

Z góry dziękuję za jakieś wskazówki!
Pozdrawiam

0

/ciach/

vBB napisał(a):

Mam też bazę danych w PostgreSQL o znanej mi strukturze.

No to pokaż tę bazę danych ze wskazaniem co i gdzie chcesz wpisać.

Pytanie, czy jest jakiś sprytny sposób na to, żeby zrobić w ramach jednej transakcji (WSZYSTKO albo NIC [w przypadku bledu])?

Tak, po prostu użyć transakcji.

Jest jakieś narzędzie pozwalające zrobić kod SQL INSERT z takiej ArrayPodst? Jeśli nie, to jak to zrobić na piechotę, ale w miarę "gentle"?

Automatu nie znam, ale elegancki sposób pewnie istnieje, ale:

  • jaka wersja Delphi?
  • jakie komponenty do bazy danych?

I na koniec - ta podana struktura rekordu T_zbior_1 na pewno jest poprawna?
Bo

T_zbior_1.zbior1

wskazuje znów na rekord T_zbior_1 i masz piękny cykl. Na pewno nie powinno być tam tak, że pole T_zbior_1.zbior_1 jest typu T_zbior_1_1 a nie jak wpisałeś T_zbior_1?
A jeśli tak to po co pokazywałeś rekordy T_zbior_1_1 i T_zbior_1_1_1, skoro one są w takim przypadku zupełnie niepotrzebne?

0
wloochacz napisał(a):

I na koniec - ta podana struktura rekordu T_zbior_1 na pewno jest poprawna?
Bo

T_zbior_1.zbior1

wskazuje znów na rekord T_zbior_1 i masz piękny cykl. Na pewno nie powinno być tam tak, że pole T_zbior_1.zbior_1 jest typu T_zbior_1_1 a nie jak wpisałeś T_zbior_1?

A jeśli tak to po co pokazywałeś rekordy T_zbior_1_1 i T_zbior_1_1_1, skoro one są w takim przypadku zupełnie niepotrzebne?

Oczywiście, pisałem z pamięci a nie kopiowałem, to tylko był przykład, ale już poprawiłem na właściwą strukturę.

Pracuje w środowisku Embarcadero Delphi XE2, komponenty do bazy mogą być dowolne, nie mam narzuconych jakichś konkretnych, ale skorzystam z ADO póki co, powinno na początek wystarczyć.

To, że trzeba użyć transakcji to wiem. Na bazach danych znam się, ale niestety tylko MSSQL i Oracle, mimo wszystko PostgreSQL to nie jest to samo, aczkolwiek logika jest taka sama praktycznie.

Bazy danych nie mogę pokazać, ale baza została stworzona na wzór struktury tych plików, tj. jeżeli np. mam 3 poziomy tablic jak na przykładzie to będą 3 tabele, w relacji jeden do wielu, tj.

"Tabela_T_zbior_1" zawiera klucz główny dla tabeli "Tabela_T_zbior_1_1", a ta zawiera klucz główny dla "Tabela_T_zbior_1_1_1" (oczywiście zawierają też odpowiednie klucze obce, wszystko jest zdefiniowane w bazie).

0
vBB napisał(a):
wloochacz napisał(a):

I na koniec - ta podana struktura rekordu T_zbior_1 na pewno jest poprawna?
Bo

T_zbior_1.zbior1

wskazuje znów na rekord T_zbior_1 i masz piękny cykl. Na pewno nie powinno być tam tak, że pole T_zbior_1.zbior_1 jest typu T_zbior_1_1 a nie jak wpisałeś T_zbior_1?

A jeśli tak to po co pokazywałeś rekordy T_zbior_1_1 i T_zbior_1_1_1, skoro one są w takim przypadku zupełnie niepotrzebne?

Oczywiście, pisałem z pamięci a nie kopiowałem, to tylko był przykład, ale już poprawiłem na właściwą strukturę.

Tylko przez takie "oczywiście" we wróżkę trzeba się bawić... Szanuj mój czas proszę.

Pracuje w środowisku Embarcadero Delphi XE2, komponenty do bazy mogą być dowolne, nie mam narzuconych jakichś konkretnych, ale skorzystam z ADO póki co, powinno na początek wystarczyć.

A dlaczego nie FireDAC?
Zrobimy to za pomocą FireDAC'a ;-)

To, że trzeba użyć transakcji to wiem. Na bazach danych znam się, ale niestety tylko MSSQL i Oracle, mimo wszystko PostgreSQL to nie jest to samo, aczkolwiek logika jest taka sama praktycznie.

Proszę Cię, to co piszesz nie współgra z tym o co pytasz...
Skoro na bazach się znasz, to transakcji za pomocnicą ADO czy FireDACa używa się dokładnie tak samo w Delphi niezalezienie od tego, z jaką bazą pracujemy.

Bazy danych nie mogę pokazać, ale baza została stworzona na wzór struktury tych plików, tj. jeżeli np. mam 3 poziomy tablic jak na przykładzie to będą 3 tabele, w relacji jeden do wielu, tj.

No bez jaj - wrzucenie 3x Create Table lub obrazka z ERD dla tych tabel, to ma być tajemnica?
Skoro tak, to ja wiem jak to zrobić, ale niestety nie mogę powiedzieć. A robi się to tako samo jak z każdą bazą danych.
Teraz ty będziesz bawił się we wróżkę.

"Tabela_T_zbior_1" zawiera klucz główny dla tabeli "Tabela_T_zbior_1_1", a ta zawiera klucz główny dla "Tabela_T_zbior_1_1_1" (oczywiście zawierają też odpowiednie klucze obce, wszystko jest zdefiniowane w bazie).

Te rekordy są w jakiejś tablicy, czy dostajesz po prostu jeden rekord typu T_zbior_1, który masz wrzucić do bazy danych?

0
wloochacz napisał(a):

A dlaczego nie FireDAC?
Zrobimy to za pomocą FireDAC'a ;-)

Jak sobie życzysz, mi jest to obojętne w zasadzie na tym etapie.

wloochacz napisał(a):

Proszę Cię, to co piszesz nie współgra z tym o co pytasz...
Skoro na bazach się znasz, to transakcji za pomocnicą ADO czy FireDACa używa się dokładnie tak samo w Delphi niezalezienie od tego, z jaką bazą pracujemy.

Niewątpliwie masz racje.

wloochacz napisał(a):

No bez jaj - wrzucenie 3x Create Table lub obrazka z ERD dla tych tabel, to ma być tajemnica?
Skoro tak, to ja wiem jak to zrobić, ale niestety nie mogę powiedzieć. A robi się to tako samo jak z każdą bazą danych.
Teraz ty będziesz bawił się we wróżkę.

Darujmy sobie takie wypowiedzi ;) Nie napisałem, że "nie chcę" tylko, że "nie mogę" - taki charakter pracy po prostu (NDA).

Baza ma kilkadziesiąt tabel, posiada chyba 6 poziomów relacji, podobnie jak i 6 poziomów zagnieżdżeń ma tablica w której mam dane, ja podałem dla przykładu 3 poziomy, z tym, że mógłbym zejść jeszcze niżej, tylko nie ma to sensu, bo dalej jest taka sama zasada (packed record w tablicy).

wloochacz napisał(a):

Te rekordy są w jakiejś tablicy, czy dostajesz po prostu jeden rekord typu T_zbior_1, który masz wrzucić do bazy danych?

Te rekordy są w tablicach trzech typów, czyli Array of T_zbior_1, Array of T_zbior_1_1 i Array of T_zbior_1_1_1, znam relację jakie pole w bazie ma odpowiadać jakiemu polu z tablicy i to wszystko w zasadzie.

0

Ok, poradziłem sobie już.

1

I bardzo dobrze, a teraz pokaż jak, żeby dla potomności zostało.

0

Okazało się jednak, czego wcześniej nie wiedziałem jeszcze, że nie jest do końca tak jak opisałem, tj. nie ma takiej "ładnej" struktury tabel w bazie.
Jest np. tabela_1 i ona ma kolumny odwołujące się do pól z różnych tablic i packed record w Delphi.
Zmapowałem po prostu konkretne rekordy do zmiennych i przekazałem je jako parametry do zapytania w pętli.

Przykładowe użycie:

ADOQuery1.Parameters.ParamByName('par').Value := par;

for I := 0 to High(ArrayPodst)-1 do
begin
   par:= ArrayPodst[I].zbior1.zbior2.pole6;
   ADOQuery1.SQL.Add('INSERT INTO Tabela_T_zbior_1 (par) VALUES (:par)');
   ADOQuery1.ExecSQL;
end;

Oczywiście cała struktura jest znacznie bardziej rozbudowana, ale jest to takie "łopatologiczne" rozwiązanie z mapowaniem (niestety 30 tabel i adekwatnie do każdej tabeli ileś kolumn).

1

Mapowanie tabel.pól z bazy danych do struktur (i odwrotnie) możesz zautomatyzować, wykorzystując w tym celu RTTI, atrybuty i oczywiście własny kod.
Tak działają ORMy np. TMS Aurelius, DORM, EntityDAC i inne.

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