SQL a záznamy z více tabulek

j0hny666

SQL a záznamy z více tabulek
« kdy: 11. 04. 2013, 17:59:07 »
Dobrý den,

mám menší problém s mezerou znalosti sql a php. Řeším teď problém kopírování záznamů. Mám hlavní tabulku, pod ní dvě tabulky s referencí na tuto tabulku a pod nimi jednu tabulku s referencemi na tyto dvě. (doufám že se to dá pochopit). Jednomu záznamu v nejvyšší tabulce odpovídá více záznamů v těch dvou pod ní a ty jsou "souřadnicemi" pro tu nejnižší.

Potřebuji takovouto sadu dat zkopírovat. Tím se ale změní id u všech záznamů (auto increment) a id reference tedy nebudou odkazovat na správné záznamy.

Rád bych se zeptal znalejších, je možné (pokud možno pouze sql, ale pokud to nejde, spokojím se s php) nějak jednoduše a přehledě sestavit dotaz tak, aby se reference přizpůsobily a nemuselo se pokádat x dotazů přes foreach? (tabulky mohou mít velké množství dat)

Předem díky za odpovědi!

« Poslední změna: 12. 04. 2013, 14:21:23 od Petr Krčmář »


j

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #1 kdy: 11. 04. 2013, 18:42:27 »
1) nedokazu si predstavit co chces resit
2) do autoincrement pole lze uplne vpohode insertovat (pripadne lze autoincrement vypnout)

j0hny666

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #2 kdy: 11. 04. 2013, 18:59:36 »
Vím, že do autoincrement můžu vkládat, ale to já nechci. Automatické číslování chci zachovat.
Potřebuji prostě udělat kopii řádku ve více tabulkách. Když nakopíruji řádek, který má své id, vytvoří se mi nové id jako další v řadě. S tímto řádkem mám propojených přes toto id více řádků z další tabulky, které chci také duplikovat. Když je ale duplikuji, budou stále odkazovat na původní řádek z první tabulky. V případě dvou tabulek by se to dalo řešit přes LastInsertId, ale já mám těch tabulek více, což toto znemožňuje.

Petr_Svetr

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #3 kdy: 11. 04. 2013, 19:19:50 »
nechapu dotaz, proc tam tazatel plete neco s autoincrement? to je prece uplne jedno, proste si napis select, ktery ti vytahne data ve forme, jake potrebujes a nasledne to obal necim jako "create table NAZEV_NOVE_TABULKY as (select col1,col2 from ....)" - tim vznikne nova tabulka NAZEV_NOVE_TABULKY, jenz bude obsahovat presne to, co ti vysype ten select. Ten priklad je z Oraclu, ale fungovat to bude urcite i jinde. Ta tabulka obsahuje jenom surova data, zadne reference, zadny autoincrement atd., nicmene ty data budou 1:1 ke zdrojovym (tedy klon, ale bez odkazu).

j0hny666

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #4 kdy: 11. 04. 2013, 19:44:25 »
Omlouvám se že jsem se vyjádřil nejasně. Jen nevím jak to správně formulovat aby to bylo srozumitelnější.

Nepotřebuji zkopírovat celé tabulky, ale pouze záznamy v nich - proto sem pletu autoincrement - data v tabulkách jsou propojeny pomocí sloupce id, který právě tuto funkci má. Při zkopírování se tedy vytvoří id nové, ale zkopírované záznamy z ostatních tabulek stále odkazují na to id, které má původní záznam, z kterého jsem kopíroval.


DK

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #5 kdy: 11. 04. 2013, 19:50:52 »
pokud jde pouze o zkopirovani dat, jde vkladat i hodnotu misto pouziti autoincrementu

pokud jde ale o nakopirovani dat do neprazdne tabulky, bude to treba delat pres script (vlozit root zaznam, ziskat posledni vlozene id, vlozit potomky (zaznamy v jinych tabulkach, ktere na root zaznamu zavisi))

MK

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #6 kdy: 11. 04. 2013, 19:55:26 »
A jak jsi ty tabulky naplnil? Toto je preci uplne stejny problem, jako kdyz vkladas nove zaznamy do tech tabulek. Akorat data neberes "odnekud", ale primo z tech tabulek. 

Pavel

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #7 kdy: 11. 04. 2013, 21:05:01 »
rieseni je moznych viac, ale kedze si neprezradil, aku databazu pouzivas, tazko povedat nieco konkretne.

vseobecne pouzitelny navod je: "priprav si nabok data ktore chces ulozit a zavolaj pre ne v cykle PHP kod ktory tie data vklada normalne.
(vo vacsine pripadov to bude najjednoduchsie riesenie)

moznost c.2. vypni pristup do databazy inym, vypni/zrus/ignoruj autoinkrement, boku si data priprav, nasukaj spat, zapni/nastav autoinkrement, spusti web

su databazy kde mozes vkladat zaznamy do autoinkrementovaneho stlpca. V tom pripade si jednoducho spocitaj nejaky vhodny posun (napr, -100000) a insertni to tak.


Petr_Svetr,j, DK: budete sa cudovat, ale svet databaz neobsahuje len implementacie, kde mozte volne zapisovat do autoinkrementovaneho stlpca.

j0hny666

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #8 kdy: 11. 04. 2013, 21:07:41 »
Pardon, zapomnel jsem uvest, pouzivam PostgreSQL 8.4. Takže bude tedy nejlepší projít to přes foreach. Tomu jsem se chtěl z prvu vyhnout, protože tak bude mnoho sql dotazů na insert, ale jak tak čtu a přemýšlím, asi to opravdu bude nejlepší řešení.

Každopádně moc díky za odpovědi, jdu si s tím hrát

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #9 kdy: 11. 04. 2013, 21:12:18 »
Ǔplne mimo, ale možno by stála za zváženie niektorá document-oriented databáza.
Mimochodom, ja som otázku pochopil na prvý krát, neviem, čo tam bolo na nepochopenie.

MK

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #10 kdy: 11. 04. 2013, 21:21:54 »
For each teda rozhodně není nejlepší způsob, já myslím, že úplně nejhorší.

Ve správně navržených datových strukturách by tohle počínání nemělo mít smysl, resp. ještě lépe, ani by ti to referenční integrita neměla dovolit. Řádky adresuješ v relačních databázích pomocí hodnot dat. Id autoinkrement je umělý primární klíč pro rychlejší JOIN, pokud ho odmyslíš, měl bys tam mít správně sloupec, nebo více sloupců tvořících primární klíč. Touto svojí akcí se snažíš o duplicitu v primárním klíči. Máš kromě Id nějaký primární klíč?

Další postup záleží na tom, jaká je odpověď na poslední větu.

Pavel

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #11 kdy: 11. 04. 2013, 21:28:02 »
Pardon, zapomnel jsem uvest, pouzivam PostgreSQL 8.4. Takže bude tedy nejlepší projít to přes foreach.

v tom pripade mozes spravit jednoduchu vec: spocitaj si ako rychlo Ti pribudaju zaznamy a kde si (aby nenastala kolizia)
povedzme mas max ID=9876 a pocitas, ze maximalne 1000 zaznamov pribudne pocas Tvojho hrania.

t.j. stanovis si Delta = 10987.
A teraz:
- insert into .. select_vratane_ID_z_tabulky1_kde_ID=ID+Delta
- insert into ...select_tabulky2_kde_odkazovany_KF_zvysis o Delta
- prestav sekvenciu pre tabulku1 za maximane ID ktore si vyrobil

Negativum je diera v IDckach ale vo vacsine pripadov na tom nikomu nezalezi.

DK

Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #12 kdy: 11. 04. 2013, 22:23:56 »
Pavel: samozrejme o tom vim, nicmene vzhledem k malo dodanym informacim jsem predpokladal nejakou z nejbeznejsi sql databazi (mysql, pripadne dane postgre)

jelikoz postgre nema "plnohodnotny" auto-increment, bylo by mozne reseni i jednorazove zvyseni AI promenne o nejvyssi ID v puvodni tabulce (takove vylepseni uvedeneho reseni), pak by nastala mezera pouze v pripade, ze v puvodni databazi jsou mezery

Logik

  • *****
  • 1 027
    • Zobrazit profil
    • E-mail
Re:SQL a kopírování záznamů z více propojených tabulek
« Odpověď #13 kdy: 11. 04. 2013, 23:21:33 »
Nechápu, co je tady k řešení:
- dumpnout (pokud je potřeba jen část dat z tabulky, tak zkopírovat do jiného schématu do tabulek stejného jména a dumpnout to jiné schéma)
- pokud jsou v cizí databázi cizí klíče s cirkulárníma závislostma, tak nastavit na DEFFERED
- přeházet tabulky dle grafu závislostí (nejdřív vložit PK a pak teprv na něj odkazující FK)
- zvýšit sekvence pro PK na MAX(Id)+1 z patřičné tabulky
- naimportovat do cílové DB
- zrušit DEFFERED u FK


Pokud je třeba data dávat do databáze, v které jsou živá data, takže hrozí konflikt u Idček, tak není problém před dumpem přičíst ke všem PK Max(ID) z patřičné tabulky v cílové databázi.