Ho 4 tabelle
Aree:
id ---
30
Processi:
id --- id_area
1-------
2-------30
Fasi:
id --- id_area --- id_processo
1-------30------------1
2-------30------------2
Macchina:
id --- id_ area --- id_processo --- id_fase
1-------30-------------1----------------1
2-------30-------------2----------------2
I dati sono legati dalle relazioni: area=>molti processi; processi=>molte fasi; fasi=>molte macchine;
Vorrei riuscire a fare la copia di questi record in un colpo solo, mantenendo le relazioni ma avendo id (chiave di ogni record) completamente nuovi.
La cosa comincia a complicarsi.. :berto: quindi ho deciso di chiedervi un parere.
In pratica per ogni tabella ho un form dal quale leggo i dati della tabella che scelgo;
Se attivo una checkbox 'copia' dirigo il $_Post all'apposito script: copia.php
Recupero alcuni dati relativi al record
Codice PHP:
$tabella=$_REQUEST["tabella"]; $record = $_GET["record"];
// la tabella è 'aree' (sto copiando l'area con tutto quello che c'è correlato in id_area;
// l'id dell'area che sto copiando è = 30
Ora copio il record principale (mi serve anche per quando copio solo quello di livello più basso, macchina ad esempio)
Codice PHP:
// copio il record di più alto livello e gli assegno un nuovo id
$risultatocolonne=mysql_query("SHOW COLUMNS FROM $tabella");
$numerocolonne=mysql_num_rows($risultatocolonne);
# Comincio a scrivere la query e setto un contatore di campi a 1
#+ (infatti l'ID l'ho praticamente inserito con quel '0' perchè nel DB è autoincrement)...
$query_main="INSERT INTO $tabella VALUES('0',";
$campiinseriti=1;
# Sfoglio le informazioni sulle colonne e, escludendo l'id (che è automatico)
#+ raccolgo il valore, passato con il form d'inserimento, corrispondente
#+ ad ogni campo e lo aggiungo alla query;
while($colonne=mysql_fetch_row($risultatocolonne)) {
if($colonne[0]!="id") {
$nomecampo=$colonne[0];
$valoredaaggiungere=addslashes($_POST[$nomecampo]);
$query_main.="'".$valoredaaggiungere."'";
# Incremento il contatore dei campi (con ++, che equivale a +1) e,
# se non sono alla fine della query, aggiungo una virgola...
$campiinseriti++;
if($campiinseriti<$numerocolonne) $query_main.=",";
}
}
$query_main.=")";
mysql_query($query_main) or die (mysql_error());
// a questo punto ho inserito il record di livello più alto
$ultimo_id = mysql_insert_id();
// in questo modo recupero il valore dell'id di più alto livello
echo "$query_main - $ultimo_id
";
// faccio l'echo per avere un minimo di debug sulla costruzione delle query
Ho dovuto definire quali tabelle controllare per vedere se ci sono record correlati all'originale; ho fatto così:
Codice PHP:
// Aree
if ($tabella == "aree"){
$array_dausare = array("processi", "fasi", "macchine");
$field_to_check = "id_area";
$field_to_check_value = $ultimo_id;}// specifico anche in quale colonna controllare
// Processi
if ($tabella == "processi"){
$array_dausare = array("fasi", "macchine");
$field_to_check = "id_processo";
$field_to_check_value = $ultimo_id;}
// Fasi
if ($tabella == "fasi"){
$array_dausare = array("macchine");
$field_to_check = "id_fase";}
// non ho messo Macchine perchè non ha relazioni sottostanti,
//ma solo di livello superiore (sbaglio?)
Poi comincio a copiare:
Codice PHP:
$lungh_array = count($array_dausare);
for($contatore=0; $contatore<$lungh_array; $contatore++) {
// quante volte fare il controllo sui possibili record relazionati (il numero di valori in array)
$query_rel="SELECT * FROM $array_dausare[$contatore] WHERE $field_to_check = '$record'";
$valori_relazionati = mysql_query($query_rel);
// fin qui ho recuperato tutti i record relazionati
(contenuti nelle tabelle indicate in $array_dausare)
if(mysql_num_rows($valori_relazionati)!=0){// se il risultato non è un insieme vuoto
while($result_relazione = mysql_fetch_array($valori_relazionati)){
// aprendo il while faccio più query su una stessa tabella individuata dal for
# Estraggo le informazioni sulle colonne della tabella e il loro numero
$risultatocolonne=mysql_query("SHOW COLUMNS FROM $array_dausare[$contatore]");
$numerocolonne=mysql_num_rows($risultatocolonne);
// questo mi serve per sapere quando mi devo fermare ad inserire valori nella query
$query="INSERT INTO $array_dausare[$contatore] VALUES('0',";
$campiinseriti=1;
# Sfoglio le informazioni sulle colonne e, escludendo l'ID (che è automatico)
#+ raccolgo il valore, passato con il form d'inserimento, corrispondente
#+ ad ogni campo e lo aggiungiamo alla query;
while($colonne=mysql_fetch_array($risultatocolonne)) {
if($colonne[0]!="id") { // id lo assegno automaticamente con '0'
$nomecampo=$colonne[0]; // il nome del campo è quello messo fra [] di tutti gli array
//$result_relazione
$valoredacopiare = addslashes($result_relazione[$nomecampo]);
// in questa variabile metto il valore dell'array per ogni $nomecampo
$query.="'".$valoredacopiare."'";
// completo la query con la variabile appena settata
$campiinseriti++;
// per ognuno di questi valori (una volta per tabella) incremento $campiinseriti di 1
if($campiinseriti<$numerocolonne) $query.=",";
// finchè non raggiungo il numero totale delle colonne di quella tabella
//aggiungo una virgola alla query
}
}
A questo punto ho fatto tutta una serie di query (INSERT) che mi consentono di fare una copia del record principale (quello da cui sono partito) e tutti quelli correlati.
Codice PHP:
$query.=")"; // chiudo le query con ")
$query=ereg_replace(",)",")",$query);
// eseguo UNA INSERT ALLA VOLTA e recupero l'ultimo id inserito
//(mi serve per metterlo nella query di update che seguirà)
mysql_query($query) or die (mysql_error());
$insert_id_sub = mysql_insert_id();
echo "$query - $insert_id_sub
";// debug
$query_update="UPDATE $array_dausare[$contatore] SET $field_to_check = $field_to_check_value";
// da completare con il WHERE
$query_update.=" WHERE id = '$insert_id_sub'";
$query_update=ereg_replace(", WHERE"," WHERE",$query_update);
mysql_query($query_update) or die (mysql_error());
echo "$query_update
"; }}} //debug
exit;
Il problema è che non riesco a settare nei campi di relazione (in particolare id_processo e id_fase) l'id del nuovo record inserito.. quello a cui la nuova fase dovrebbe essere correlata (cioè il nuovo processo ad esempio).
Ho provato a mettere degli UPDATE subito dopo le INSERT recuperando l'ultimo id inserito del sovrastante.. ma non riesco a perfezionarlo, mi incarto!
Spero di non esser stato troppo prolisso.
Qualcuno ha consigli su metodi meno empirici del mio?