WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   MySql: Uppdatera tabell A med rader från B (https://www.wn.se/forum/showthread.php?t=33580)

radioaktivitet 2008-11-27 16:19

Jag har två tabeller, A och B. Tabellerna har exakt samma tabelldefinition, men olika data. Primärnyckel finns (produkt_id).

Nu vill jag uppdatera tabell A, med alla rader från tabell B.

Dvs någonting sådant här:

Kod:

UPDATE TABLE A SELECT * FROM TABLE B
Men jag får det inte att fungera. Jag får meddelandet "You have an error in your SQL syntax"

Här är dokumentationen:
http://dev.mysql.com/doc/refman/5.0/en/update.html

Någon som vet vad jag gjort för fel?

orreborre 2008-11-27 17:00

INSERT INTO A SELECT * FROM B
borde fungera...
Eller varför ska du uppdatera?

mbomelin 2008-11-27 17:55

vill du inte ha dubletter så bör REPLACE INTO A SELECT * FROM B funka... eller?

Magnus_A 2008-11-27 18:06

Resultatet beror i så fall på om det finns gamla rader i A som inte har sin motsvarighet i B.
Vill man att innehållet i A ska bli helt identiskt med B bör man tömma tabellen innan:
truncate table A;
insert into A select * from B;

radioaktivitet 2008-11-27 19:25

Varje dag kopierar jag ett antal rader från tabell A till tabell B. Tabell B jobbar jag mot under dagen. Sedan i slutet av dagen vill jag se till att all data från tabell B kommer tillbaks till A. Ingen rader tas bort/läggs till tabell B. Jag bara manipulerar den befintliga datan i tabell B.

Därför tänkte jag att en update räcker.

Replace skulle nog fungera. Men en replace är ju en delete och en insert, dvs två operationer. Tar förmodligen dubbelt så lång tid att exekvera. Helst skulle jag vilja göra en update. Men det kanske inte går?

Edit. Tack för alla svar förresten :)

orreborre 2008-11-27 20:57

Du kan bara uppdatera en rad om den redan finns och som jag förstått det vill du föra över nya rader och då fungerar det inte med en UPDATE.

radioaktivitet 2008-11-27 21:07

Då tror jag att du missförstod det jag skrev. Jag vill bara uppdatera rader som redan finns. Inte ta bort och inte lägga till nya rader.

Fungerar det med en update då, och vad är det för fel på min sql-fråga?

jimmie 2008-11-27 21:28

http://dev.mysql.com/doc/refman/5.0/en/ins...-duplicate.html

Så använder du values(xyz) för att göra update för dom rader som redan finns.

Lycka till.

Magnus_A 2008-11-27 21:33

Replace into gör det du vill, är standard förfaringssätt och går snabbt.
Vill du ändå använda update av nån anledning skriver du så här: update A, B set A.kolumn1 = B.kolumn1, (osv)...... where A.indexkolumn = B.indexkolumn;

radioaktivitet 2008-11-28 10:14

Tack allihopa. Replace blev lösningen :-)

radioaktivitet 2008-12-05 13:07

Både Replace och Update fungerade. Update var aningen snabbare (endast en operation, jämfört med replace som är två operationer).

Men varje gång jag kör min fråga (som trots att jag använder update tar ca 5 minuter att exekvera) så får jag "too many connections" när jag försöker ansluta för att exekvera andra frågor.

Förmodligen beror det på att tabellen låses när jag kör min Update. Jag kör med myisam tabeller.

Jag försökte sätta UPDATE LOW_PRIORITY, men det hjälpte inte. Samma fel.

Några tips på lösning?

Magnus_A 2008-12-05 15:57

Är det en produktionsserver där besökare ansluter?
Vad säger show processlist?
Det finns alltid en extra anslutning för root möjlig för att kunna köra t ex show processlist.

radioaktivitet 2008-12-05 16:01

Ja.
Alla processer står "Locked".

Clarence 2008-12-05 17:53

Enkel fix på problemet, om jag inte missat något, är nog att skapa en kopia av strukturen på tabell a, en insert select från tabell a till denna kopia, rensa tabell a och sen köra din update från denna kopia. Alternativt rename på tabell a och sen skapa en ny tabell a om även insert select tar tid.

radioaktivitet 2008-12-07 09:23

Clarence: jag förstår inte riktigt vad du menar. Jag vill få datan från tabell A till tabell B. Hur kan en ny temporär tabell hjälpa mig?

Magnus_A 2008-12-07 12:36

Utan att veta i detalj gissar jag på att någon annan fråga villl skriva till dessa tabeller som är låsta i 5 minuter, vilket inte går. Antar att du jobbar på en produktionsserver där andra användare (besökare) jobbar mot dina tabeller.
Clarences lösning bygger på att lyfta ut uppdatering till tabeller som ingen annan ställer frågor emot under tiden. De får vara i fred och hindrar inte annan användning genom att hålla tabellen låst.
När uppdateringen är klar efter 5 minuter kopierar du hela tabellen in i produktionsmiljön genom att trunkera befintlig tabell, och lägga in alla rader från den temporära uppdaterade tabellen. En sådan operation är mycken snabbare och de hinner inte bildas en massa köer.


Alla tider är GMT +2. Klockan är nu 21:57.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson