duplicare record | SQL & MySQL

Topic: Pubblico - Composto da 8 Posts di 2 Utenti.

01 Ottobre, 2011 08:10 #1
Febo
Utente

Febo
Registrato: Oct, 2011
Posts: 11
Offline

Un saluto a tutti.

Quali istruzioni, come faccio a duplicare un record da una tabella master (master) e suoi dettagli (tabella dettagli) verso un nuovo/i record, sempre nella stessa tabella (master e quindi dettagli), con campo master ID (auto incrementale univoco)? Ho provato con la tabella master e va bene. Ma poi devo recuperare il nuovo ID per duplicare i record della tabella dettagli. Qualche linea di codice...

01 Ottobre, 2011 09:33 #2
fuser
Utente

fuser
Registrato: Aug, 2011
Posts: 86
Offline

Non sono sicuro di aver capito, ma dovrebbe essere:
INSERT INTO master SELECT campo1, campo2, ... FROM master;
(non selezionare l'id, altrimenti tenti di duplicare anche quello)
e poi:
INSERT INTO dettagli SELECT LAST_INSERT_ID() AS id, campo1, campo 2... FROM master;

Oppure, se i record sono molti e giustamente non vuoi lanciare 2 query per ogni riga, fai un trigger.

Una curiosità: sei già il secondo che leggo in pochi giorni che vuole duplicare dei record nella stessa tabella, cosa che io non ho mai fatto; perchè lo fai?

01 Ottobre, 2011 09:57 #3
Febo
Utente

Febo
Registrato: Oct, 2011
Posts: 11
Offline
Una curiosità: sei già il secondo che leggo in pochi giorni che vuole duplicare dei record nella stessa tabella, cosa che io non ho mai fatto; perchè lo fai?

Ho bisogno di richiedere offerte da vari fornitori. Il protocollo del master (ID) deve essere univoco.

Ti posto il mio codice. Funziona ma non mi piace. Se mentre recuperi il MAX del dettaglio qualcuno inserisce un nuovo record nel master appunto?...

insert into `ordini`
( `vs_protocollo` ,
`id_ditta_FK` ,
`data` ,
`riferimento_cantiere` ,
`stampa` ,
`id_tipo_documento_FK`,
`id_pagamento_FK` ,
`id_ubicazione_FK` ,
`id_termine_consegna_FK`)
SELECT
ordini.vs_protocollo,
ordini.id_ditta_FK,
ordini.`data`,
ordini.riferimento_cantiere,
ordini.stampa,
ordini.id_tipo_documento_FK,
ordini.id_pagamento_FK,
ordini.id_ubicazione_FK,
ordini.id_termine_consegna_FK
FROM
ordini
WHERE
ordini.id_ordine = :ID;

commit;

insert into `prodotti_has_ordini`

( `id_ordine_FK`,
`id_unita_misura_FK`,
`dettaglio` ,
`quantita` ,
`prezzo`,
`sconto` ,
`tassa` ,
`totale`)
SELECT
(select MAX(id_ordine)from `ordini`),
prodotti_has_ordini.id_unita_misura_FK,
prodotti_has_ordini.dettaglio,
prodotti_has_ordini.quantita,
prodotti_has_ordini.prezzo,
prodotti_has_ordini.sconto,
prodotti_has_ordini.tassa,
prodotti_has_ordini.totale
FROM
prodotti_has_ordini
WHERE
prodotti_has_ordini.id_ordine_FK = (select id_ordine from ordini where id_ordine=:ID);

commit;

01 Ottobre, 2011 10:05 #4
Febo
Utente

Febo
Registrato: Oct, 2011
Posts: 11
Offline

...la ultima select e' inutile in quanto basta mettere l' :ID.

01 Ottobre, 2011 12:27 #5
fuser
Utente

fuser
Registrato: Aug, 2011
Posts: 86
Offline

Io userei last_insert_id (che è thread-safe) e farei una sola commit

01 Ottobre, 2011 14:14 #6
Febo
Utente

Febo
Registrato: Oct, 2011
Posts: 11
Offline

Quindi:

insert into `ordini`
SELECT
NULL,
ordini.vs_protocollo,
ordini.id_ditta_FK,
ordini.`data`,
ordini.riferimento_cantiere,
ordini.stampa,
ordini.id_tipo_documento_FK,
ordini.id_pagamento_FK,
ordini.id_ubicazione_FK,
ordini.id_termine_consegna_FK
FROM
ordini
WHERE
ordini.id_ordine = :ID;

SELECT @last:=LAST_INSERT_ID();

insert into `prodotti_has_ordini`
SELECT
NULL,
@last,
`dettaglio` ,
`quantita`,
`prezzo` ,
`sconto` ,
`tassa` ,
`totale` ,
`id_unita_misura_FK`
FROM
prodotti_has_ordini
WHERE
prodotti_has_ordini.id_ordine_FK = :ID;

commit;

Purtroppo il componente script (zeoslib) non riconosce il token ":=LAST_INSERT_ID()". Una stored procedure? e si passa l':ID?

02 Ottobre, 2011 00:06 #7
fuser
Utente

fuser
Registrato: Aug, 2011
Posts: 86
Offline

Mi dispiace, non conosco zeoslib.
LAST_INSERT_ID() non è una stored procedure ma una funzione nativa di MySQL e non si passa nessun parametro. Restituisce l'ultimo id che è stato inserito dalla connessione corrente.

02 Ottobre, 2011 06:47 #8
Febo
Utente

Febo
Registrato: Oct, 2011
Posts: 11
Offline

Ti ringrazio dell'aiuto. alla fine ho creato una procedura, gli passo param1 (:ID master) e mi restituisce param2 (:ID nouvo master):

CREATE DEFINER = 'root'@'localhost' PROCEDURE `new_proc`(
IN param1 INTEGER(11),
OUT param2 INTEGER(11)
)
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
insert into `ordini`

SELECT
NULL,
ordini.vs_protocollo,
ordini.id_ditta_FK,
ordini.`data`,
ordini.riferimento_cantiere,
ordini.stampa,
ordini.id_tipo_documento_FK,
ordini.id_pagamento_FK,
ordini.id_ubicazione_FK,
ordini.id_termine_consegna_FK
FROM
ordini
WHERE
ordini.id_ordine = param1;

SELECT @last:=LAST_INSERT_ID();

insert into prodotti_has_ordini
SELECT
NULL,
@last,
prodotti_has_ordini.dettaglio,
prodotti_has_ordini.quantita,
prodotti_has_ordini.prezzo,
prodotti_has_ordini.sconto,
prodotti_has_ordini.tassa,
prodotti_has_ordini.totale,
prodotti_has_ordini.id_unita_misura_FK
FROM
prodotti_has_ordini
WHERE
prodotti_has_ordini.id_ordine_FK = param1;

SET param2 = @last;
COMMIT;
END;

Condividi su:

Loggati o Registrati per replicare