2013-05-09 5 views
6

Ich bin Tring diesealle Zeilen in einer Tabelle duplizieren und verhindern, doppelte Schlüssel

  • alle Zeilen in einer Tabelle mit dem Namen Blogs Holen Sie tun.
  • sie in einer temporären Datenbank kopieren
  • Bearbeiten Sie die Sprache Feld dieser temporären Tabelle Datensätze
  • in die Blogs Tabelle einfügen

Und ich bin es so versuchen:

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2; 
UPDATE tmptable SET lan = 1; 
INSERT INTO blogs SELECT * FROM tmptable; dump database tmptable; 

Aber von kors bekomme ich doppelten Schlüsselfehler ...

Wie kann ich es verhindern?

-EDIT-

I Tried:

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2; 
UPDATE tmptable SET lan = 1; 
ALTER TABLE tmptable DROP id; 
INSERT INTO blogs SELECT * FROM tmptable; dump database tmptable; 

Aber dann die Column count doesn't match value count at row 1

-EDIT-

Ich glaube, das funktioniert (und es tat, weil ich weiß, wie viele Datensätze existieren)

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2; 
UPDATE tmptable SET lan = 1; 
UPDATE tmptable SET id = id + 1000; 
INSERT INTO blogs SELECT * FROM tmptable; 

Aber wie kann ich es richtig machen? (Set nur den nächsten avaliable autoincrement Wert für Primärschlüssel (id) (ohne PHP/gleichermaßen))

-EDIT-

vielleicht so etwas wie dieses ???

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2; 
UPDATE tmptable SET lan = 1; 
UPDATE tmptable SET id = id + (SELECT id FROM blogs ORDER BY id DESC LIMIT 1); 
INSERT INTO blogs SELECT * FROM tmptable; 
+0

die id der blogs table ist eine identität? – TeKapa

+0

ist der Primärschlüssel, einzigartig und Autoincrement. Ja! –

+0

Warum ändern Sie nicht einfach Ihre INSERT-Anweisung, um ON DUPLICATE KEY UPDATE zu verwenden? –

Antwort

4
CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2; 
UPDATE tmptable SET lan = 1; 
alter table tmptable drop column id; 
INSERT INTO blogs SELECT NULL,tmptable.* FROM tmptable; 

Angenommen, die Spalte "id" ist die erste Spalte.

+0

Ich mag diesen :) –

0
UPDATE blogs SET lan = 1 WHERE lan = 2; 

einfach die Abfrage auf Ihrer ursprünglichen Tabelle ausführen.

Ich will nicht die Sprache ändern, möchte ich eine weitere Kopie von alle Datensätze speichern und dieses Kopien eine andere Sprache asign

In diesem Fall fallen die Primärschlüssel aus Ihrer temporäre Tabelle. Fügen Sie die Primärschlüsselspalte nicht ein, wenn Sie die Zeilen einfügen:

INSERT INTO blogs (title, lan) SELECT * FROM tmptable; 
+1

NOOOOOO .... Ich möchte die Sprache nicht ändern, ich möchte eine weitere Kopie aller Datensätze speichern und zuordnen, dass dies eine andere Sprache kopiert –

12

Keine temporäre Tabelle benötigt.

INSERT INTO blogs (lan, col1, col2, col3, ...) 
SELECT 1, col1, col2, col3, ... 
FROM blogs 
WHERE lan = 2 

ersetzen col1, col2, col3, ... mit einer Liste aller Spalten außer lan und id.

+0

das sollte funktionieren! – TeKapa

+1

Problem von diesem ist, dass Sie die Spur aller Felder haben müssen. –

+2

Ist das etwas, das Sie häufig tun müssen? Ändert sich Ihr Tabellenschema stark? Wenn dies der Fall ist, könnten Sie eine gespeicherte Prozedur schreiben, die das SQL dynamisch aus information_schema generiert. – Barmar

0

Mit vorbereitete Anweisung Sie das Informationsschema für die Spalte abfragen, können Sie verwenden möchten, und dann schmieden, um die Abfrage, die Sie ausführen möchten:

hier ein Beispiel für Ihren Fall:

-- first query all the blogs column minus id and lan 

SELECT GROUP_CONCAT(c.COLUMN_NAME) 
INTO @cols 
FROM INFORMATION_SCHEMA.COLUMNS c 
WHERE 
c.TABLE_NAME = 'blogs' 
AND c.COLUMN_NAME not in ('id', 'lan'); 

-- second build the query with the gathered columns 
-- like INSERT INTO blogs(lan, col1, ...) SELECT 2, col1, ... FROM blogs WHERE lan=1 

SET @sql=CONCAT(CONCAT(CONCAT(CONCAT('INSERT INTO blogs (lan,', @cols), 
       ') SELECT 2,'), @cols), ' FROM blogs WHERE lan=1'); 

-- prepare the statement  
PREPARE stmt FROM @sql; 

-- and last run the insert 
EXECUTE stmt; 
1

Bitte versuchen Sie es folgende sql. Eine ähnliche SQL FIDDLE

CREATE TEMPORARY TABLE tmptable SELECT * FROM blogs WHERE lan = 2; 
    UPDATE tmptable SET lan = 1; 
    UPDATE tmptable SET id = (select @val:[email protected]+1 from(select @val:=(select max(id) from blogs)) t) 
    INSERT INTO blogs SELECT * FROM tmptable; 

Hoffnung, das hilft.