2013-05-09 8 views
6

Tring di fare questoduplicare tutti i righe di una tabella e prevenire le chiavi duplicate

  • Ottenere tutte le righe in un blog di nome tabella.
  • li copia in un database temporaneo
  • Modificare il campo lingua di questo record della tabella temporanei
  • inserire nella tabella blog

E sto cercando in questo modo:

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

Ma di solito ottengo l'errore della chiave duplicato ...

Come posso impedirlo?

operativa -Editazione-

ho provato:

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; 

Ma poi il Column count doesn't match value count at row 1

operativa -Editazione-

Credo che questo sarà il lavoro (e lo ha fatto, perché io so come esistono molti documenti)

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; 

Ma come posso farlo correttamente? (Basta impostare il valore successivo autoincrement avaliable per la chiave primaria (id) (senza PHP/simili))

operativa -Editazione-

forse qualcosa di simile ???

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

l'id della tabella dei blog è un'identità? – TeKapa

+0

è la sua chiave primaria, unica e autoincrementata. sì! –

+0

Perché non basta modificare la tua istruzione INSERT per utilizzare ON DUPLICATE KEY UPDATE? –

risposta

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; 

Assumed, la colonna "id" è la prima col.

+0

Mi piace questo :) –

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

È sufficiente eseguire la query sulla tabella originale.

Non voglio cambiare la lingua, voglio salvare un'altra copia tutti i record e assegnare dei questa copia una lingua diversa

In tal caso, eliminare la chiave primaria dal tavolo temporaneo. Quando si inserisce indietro le righe, non includere la colonna chiave primaria:

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

NOOOOOO .... Non voglio cambiare la lingua, voglio salvare un'altra copia di tutti i record e assegnare a questa copia una lingua diversa –

12

Nessuna tabella temporaneo necessario.

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

Sostituire col1, col2, col3, ... con un elenco di tutte le colonne tranne lan e id.

+0

questo dovrebbe funzionare! – TeKapa

+1

Il problema è che devi avere la traccia di tutti i campi .. –

+2

È qualcosa che devi fare spesso? Il tuo schema di tabella cambia molto? In tal caso, è possibile scrivere una stored procedure che generi SQL in modo dinamico da information_schema. – Barmar

0

Utilizzando dichiarazione preparata è possibile interrogare lo schema informazioni per la colonna che si desidera utilizzare e quindi stringere la query che si desidera eseguire:

qui un esempio per il vostro caso:

-- 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

Riprova seguendo sql. Un simile 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; 

Spero che questo aiuti.

Problemi correlati