lunes, 27 de abril de 2009

Manual de PHP 77. MySQL: Borrar registros y salvar datos

Sintaxis MySQL para borrado de registros

La sintaxis MySQL para las sentencia de borrado de registros de una tabla puede contener las siguientes cláusulas que, al igual que ocurría en casos anteriores, pueden tener categoría de obligatorias u opcionales.

La secuencia en la que deben estar indicadas en la sentencia es idéntica al orden en que están descritas aquí.

-- Para leer la entrada completa, pulse en el enlace LEER MÁS --




DELETE

Tiene carácter obligatorio. Debe ser la primera palabra de la sentencia e indica a MySQL que tratamos de borrar uno o más registros.

LOW_PRIORITY

Es opcional e indica a MySQL que espere para realizar la actualización a que terminen las consultas del fichero (en el caso de haber alguna en proceso).

FROM

Tiene carácter obligatorio y debe preceder a la definición de la tabla en la que se pretende eliminar registros.

tabla

Es obligatoria e indica el nombre de la tabla en la que pretendemos efectuar el borrado o eliminación de los registros.

WHERE

Es un campo opcional y su comportamiento es idéntico al señalado en al mencionar el proceso de consultas.

LIMIT n

La opción LIMIT es opcional y propia de MySQL.

Su finalidad es limitar el tiempo de ejecución del comando DELETE ya que cuando está activada devuelve el control al potencial cliente después de borrar n registros, con lo que en procesos de borrados muy largos (ficheros de gran tamaño) no obliga a esperar a borrado total para proceder a la consulta de la tabla.

Cuando se utiliza esta opción, la sentencia DELETE debe repetirse hasta que el número de registros pendientes de borrado sea inferior al valor de n.


Optimización de tablas

Cuando se ejecuta la sentencia DELETE -pese a que son eliminados los valores de los campos- se conservan las posiciones de los registros borrados, con lo cual no se reduce el tamaño de la tabla.

Esas posiciones de registro serán utilizadas por MySQL para escribir los registros que se vayan añadiendo después del proceso de borrado.

Para eliminar esos registros vacíos y reducir el tamaño de una tabla, MySQL dispone de una sentencia que es la siguiente:

OPTIMIZE TABLE tabla

Esta sentencia -que debe usarse después de un proceso de borrado amplio- depura la tabla eliminando los registros inutilizados por el proceso DELETE, con lo que logra una reducción del tamaño de la tabla a su dimensión óptima.


Los arrays de la sentencia SELECT

Aunque están comentados en los códigos fuente de los scripts queremos reiterar aquí para hacer algunas precisiones sobre los resultados de las consultas de tablas.

Se trata de los índices de los arrays que se obtienen mediante las funciones:

mysql_fetch_array()
y
mysql_fetch_row()

Los índices escalares, en ambos casos, cuanto tratan información obtenida mediante una sentencia SELECT coinciden con el orden en el que han sido establecidos los campos en esa instrucción concreta. De modo que el primer de esos nombres de campos sería asociado con el índice cero de estos array, el segundo con el índice 1 y así sucesivamente.

En el caso del array asociativo devuelto por la primera de estas funciones, los índices coinciden siempre con los nombres de los campos de los que han sido extraídos los datos.

En el caso de que la consulta afecte a varias tablas (recuerda que los campos se asignan poniendo tabla.campo (nombre de la tabla y nombre del campo) el índice del array asociativo sería esa expresión con el punto incluido.

Borrar todos los registros de una tabla

La sentencia MySQL que permite borrar todos los registros de una tabla es la siguiente:

DELETE FROM tabla
Ten muy presente que con esta sentencia -en la que no aparece WHERE- se BORRARÁN TODOS LOS REGISTROS DE LA TABLA.

Respecto a otras posibles opciones no difiere en nada de lo indicado en la página anterior. Simplemente habría que sustituir en aquellos script UPDATE por DELETE. Borrar un registro no es otra cosa que un caso particular de modificación.


Integridad referencial tras el borrado de una tabla

¿Recuerdas el ejemplo de las pruebas de selección de astronautas? ¿Recuerdas que las tres tablas de puntuaciones habían sido creadas a partir de la tabla de datos de los aspirantes? ¿Qué ocurriría si borrásemos uno o varios registros de una de ellas? ¿Qué ocurriría se después de crear esas tablas añadiésemos nuevos aspirantes a la lista de candidatos?

Es obvio que si no hacemos algo para evitarlo se perdería la integridad referencial - la relación uno a uno - entre los registros de esas tablas.

Ocurriría que no todos los individuos que están incluidos en una de esas tablas lo estarían en las demás y por tanto, al ejecutar consultas o modificaciones posteriores correríamos el riesgo de que se produjeran errores.

Esa situación es fácilmente evitable modificando ligeramente los scripts con los que se realizan los procesos de altas y bajas.
Bastaría con añadirles algunas sentencias que cada vez que se efectúa un alta o baja en el fichero de datos personales efectúen el mismo proceso en todos los demás ficheros relacionados con aquel.

Aquí tienes comentado el código fuente de la modificación añadida al script que registra los nuevos aspirantes en el fichero de altas de la tabla demo4. Con esta modificación se actualizarían automáticamente los ficheros demodat1, demodat2 y demodat3 cada vez que se añadiera un nuevo aspirante.

El formulario no requiere ninguna modificación, los cambios sólo es necesario realizarlos en el script que realiza la inserción.


<?

# recogemos en una variable el nombre de BASE DE DATOS

$base="ejemplos";



# recogemos en una variable el nombre de la TABLA

$tabla="demo4";



# recoger y adaptar las variables pasadas desde el formulario

# ni el DNI ni los nombres y apellidos necesitan ninguna modificacion

# por eso los pasamos a la variable intermedia directamente

/* estas variables intermedias podrían evitarse. El hecho de usarlas

obedece unicamente a un intento de mayor claridad en la interpretación

de este codigo fuente */

$v1=$_POST['p_v1'];

$v2=$_POST['p_v2'];

$v3=$_POST['p_v3'];

$v4=$_POST['p_v4'];



/* Leemos el array pv__5 y lo recogemos

en un array escalar de indices autonumericos

(nacimiento) teniendo en cuenta que el orde sería

dia, mes y año, ya que así lo hemos insertado

en los indices del formulario */



foreach ($_POST['p_v5'] as $valor){

$nacimiento[]=$valor;

}

/* creamos la variable fecha de nacimiento

ENCADENANDO el array anterior

FIJATE QUE LO HACEMOS EN ORDEN INVERSO

PORQUE MySQL REQUIERE FECHAS CON FORMATO

AÑO-MES-DIA (AAAA-MM-DD) */

$v5=$nacimiento[2]."-".$nacimiento[1]."-".$nacimiento[0];



# la variable Sexo la recogemos sin modificaciones

# ya que desde el formulario solo recibimos

# valor M ó valor F

$v6=$_POST['p_v6'];

/* Leemos el array pv__5 y lo recogemos

en un array escalar (hora) de indices autonumericos

teniendo en cuenta que el orde sería

dia, mes y año, ya que así lo hemos insertado

en los indices del formulario */

foreach ($_POST['p_v7'] as $valor){

$hora[]=$valor;

}



/* encadenamos los elementos del array hora en formato válido

MySQL, es decir: hora:minutos:segundos (hh:mm:ss) */

$v7=$hora[0].":".$hora[1].":".$hora[2];





# la variable $p_v8 puede contener valores

# 0 (no fumador) ó 1 (si fumador)

# con este bucle asignamos NULL para el primero de los casos

# o CADENA VACIA para el segundo

# ¡¡Atención......

# fijate como pasamos la cadena vacia

# y fijate que en el INSERT no ponemos la variable $v8 entre comillas

# es la excepción para el tipo de variable CHAR(O)

# LA UNICA QUE NO PASAMOS ENTRECOMILLADA

if ($_POST['p_v8']==0) {

$v8='"\n"';

}else{

$v8='""';

}



# el truco de asignar en el formulario valores 1,2,4,8,16,32 a las opciones de idioma

# nos permite sumarlos aquí para obtener el valor conjunto

# aqui se suman todos los valores de la matriz pasada desde el formulario

foreach($_POST['p_v9'] as $valor) {

$v9+=$valor;

};



# establecemos la conexion con el servidor

$c=mysql_connect("localhost","pepe","pepa");



#asiganamos la conexión a una base de datos determinada

mysql_select_db($base,$c);



# AÑADIMOS EL NUEVO REGISTRO

/* CUIDADO.....

SOLO LAS VARIABLES NUMERICAS VAN SIN COMILLAS AL INSERTAR LOS VALOES

OBSERVA EN VALUES QUE LAS VARIABLES NO NUMERICAS SE INSERTAN

ENTRE COMILLAS..... */

mysql_query("INSERT $tabla (DNI,Nombre,Apellido1,Apellido2, Nacimiento,Sexo,Hora,Fumador,Idiomas) VALUES ('$v1','$v2','$v3','$v4','$v5','$v6','$v7',$v8,'$v9')",$c);



#comprobamos el resultado de la insercion

# el error CERO significa NO ERROR

# el error 1062 significa Clave duplicada

# en otros errores forzamos a que nos ponga el número de error

# y el significado de ese error (aunque sea en ingles)....

f (mysql_errno($c)==0){echo "<h2>Registro AÑADIDO</b></H2>";

}else{

if (mysql_errno($c)==1062){echo "<h2>No ha podido añadirse el registro<br>Ya existe un campo con este DNI</h2>";

}else{

$numerror=mysql_errno($c);

$descrerror=mysql_error($c);

echo "Se ha producido un error nº $numerror que corresponde a: $descrerror <br>";

}



}

##################################################################################

# #

# MODIFICACION DEL EJEMPLO 173 PARA LA ACTUALIZACION SIMULTANEA DE LAS TABLAS #

# demodat1, demodat2, demodat3 cuando se produce un ALTA #

# en la tabla demo4 #

##################################################################################



# una vez añadimo el registo en la tabla demo4

#procedemos a añadirlo tambien en las tablas demodat1, demodat2, demodat3

# que estan vinculadas referencialmente a aquella

#

# no necesitamos añadir ninguna condicion ya que al ser el campo DNI

# una clave principal en las tres tablas

# si la clave existiera no no efectuaría la inserción





mysql_query("INSERT demodat1 (DNI,Puntos) VALUES ('$v1',0)",$c);

mysql_query("INSERT demodat2 (DNI,Puntos) VALUES ('$v1',0)",$c);

mysql_query("INSERT demodat3 (DNI,Puntos) VALUES ('$v1',0)",$c);



##################################################################################

# FIN DE LA MODIFICACION #

##################################################################################

# cerramos la conexion

mysql_close();

?>


Hecho este pequeño inciso -creemos que importante y necesario - continuaremos con la referencia al borrado de registros.

En este ejemplo, tienes el código fuente de un script que realiza el borrado de un registo –mediante un formulario en el que se inserta el DNI– tanto en la tabla demo4 como demodat1, demodat2 y demodat3 manteniendo la integridad referencial entre los cuatro ficheros.


<?

# recogemos en una variable el nombre de BASE DE DATOS

$base="ejemplos";



# recogemos en una variable el nombre de la TABLA

$tabla="demo4";



# recogemos el post del formulario

$Penitente=$_POST['Penitente'];

# establecemos la conexion con el servidor

$conexion=mysql_connect("localhost","pepe","pepa");



#asiganamos la conexión a una base de datos determinada

mysql_select_db($base,$conexion);

# borramos el REGISTRO SELECCIONADO MEDIANTE WHERE

mysql_query("DELETE FROM demo4 WHERE (DNI=$Penitente)",$conexion);



# creamos un mensaje de confirmación del evento

$num_borrados=mysql_affected_rows($conexion);

$avisar="<BR>Se han borrado ".$num_borrados." registros<BR> en todas las tablas relacionadas<BR>";

mysql_query("DELETE FROM demodat1 WHERE (DNI=$Penitente)",$conexion);

mysql_query("DELETE FROM demodat2 WHERE (DNI=$Penitente) ",$conexion);

mysql_query("DELETE FROM demodat3 WHERE(DNI=$Penitente)",$conexion);



# cerramos la conexion

mysql_close();



#####################################################

#fijate como pasamos el valor del mensaje de aviso #

#####################################################

# para pasar valores a PHP hay la opcion de añadir a la direccion

# URL del script el simbolo de cerrar interrogacion

# seguido del nombre de la variable con la que será transferido

# el signo igual y el valor de la variable

#

# si quieres pasar mas de una variable la sintaxis sería

# http://loquesea.php?variable1=valor1&variable2=valor2&variable3=valor3

?>



<script language='JavaScript'>

<? echo "window.self.location='ejemplo204.php?avisa=$avisar'" ?>

</script>

Borrar registros seleccionándolos de una lista

En el ejemplo siguiente tienes el código para utilizar la cláusula WHERE en un proceso de borrado de registros que presenta un formulario que contiene una lista con todos los registros actuales y una casilla de verificación por cada uno.

Al marcar las casillas y enviar el formulario el script que recibe los datos procede al borrado de todos los registros marcados en todas la tablas afectadas.

Formulario:


<html>

<head>

<title>Formulario para ELIMINAR REGISTROS de la tabla demo4, demodat1, demodat2 y demodat3</title>

</head>

<body>

<?

# definimos una variable con el NOMBRE DE LA BASE DE DATOS

$base="ejemplos";

# establecemos la conexión con el servidor

$conexion=mysql_connect ("localhost","pepe","pepa");



#Seleccionamos la BASE DE DATOS en la que PRETENDEMOS TRABAJAR

mysql_select_db ($base, $conexion);

#creamos una consulta de las bases de datos demo4 y demodat2

# esta segunda es la tabla de puntuaciones de la segunda prueba

# seleccionamos los campos DNI de ambas tablas

# y nombre y apellidos de la primera

# establecemos como condicion la IGUALDAD DE LOS DNI en TODAS LAS BASES



$resultado=mysql_query("SELECT demo4.DNI,demo4.Nombre,demo4.Apellido1, demo4.Apellido2 ,demodat1.Puntos, demodat2.Puntos, demodat3.Puntos FROM demo4, demodat1, demodat2, demodat3 WHERE (demo4.DNI=demodat1.DNI AND demo4.DNI=demodat2.DNI AND demo4.DNI=demodat3.DNI) ",$conexion);



# presentamos la salida en forma de tabla HTML

# estos son los encabezados

echo "<table align=center border=2 bgcolor='#F0FFFF'>";

echo "<tr bgcolor='#ffffff'><td colspan=5 align=center>Para BORRAR marca la casilla correspondiente al registro a eliminar</td><tr bgcolor='#ffffff'>";

echo "<td align=center>Datos del aspirante</td>";

echo "<td align=center>Punt 1</td>";

echo "<td align=center>Punt 2</td>";

echo "<td align=center>Punt 3</td>";

echo "<td align=center>Borrar</td><tr>";



#escribimos la etiqueta de apertura de un formulario como method=post

# como action ponemos la direccion de la página que realizará las actualizaciones

# en este caso sera ejemplo207.php



echo "<form name='modificar' method=post action='ejemplo207.php'>";



while($salida = mysql_fetch_array($resultado)){



# escribimos un bucle que nos lea desde el indice 0 hasta el indice 6

# de la matriz de salida ya que los indices 0,1,2,3,4...

# se corresponden con el número de orden tal como fueron establecidos

# los campos en la opción SELECT: 0 es el indice del primero

# 1 el de segundo, 2 el del tercero, etc. etc.



# empezamos el bucle for en $i=1 porque $i=0 corresponderia al DNI

# y esta vez NO VAMOS A PRESENTAR EN PANTALLA ESE NUMERO

# .... cuestion de estética... unicamente

#

# los condicionales anidados solo tiene una finalidad estética

# se trata de Nombre y apellidos aparezcan en la misma celda de la tabla

# por eso.. delante de nombre ponemos <td> ($i=1)pero...

# no lo hacemos ni delante de Apellido 1 ni de apellido 2...

# pero ...detrás de Apellido dos tenemos que cerrar la etiqueta </td>

#

# en los demás casos, usamos celdas independientes y por tanto

# ponemos <td> antes del valor y </td> detrás

for ($i=1;$i<7;$i++){



if($i==1) {

echo "<td>",$salida[$i]," ";

}else{

if ($i==2) {

echo $salida[$i]," ";

}else{

if ($i==3) {

echo $salida[$i],"</td> ";

}else{

echo "<td>",$salida[$i],"</td>";

}

}

}

}



# despues de recoger los datos añadimos un campo de formulario

# identificado por un NAME que es una matriz (borra) cuyo indice es el DNI del campo consultado

# al ponerle como VALUE='Si" lo que estamos haciendo es que

# cuando este "marcada" la casilla ese elemento de la matriz tome valor Si

# cuando "no está esté marcada" tomará valor NULL y por lo tanto

# NO SERÁ ENVIADA POR EL METHOD POST

echo "<td align=center> <input type=checkbox name=borra[$salida[0]] value='Si'></td><tr>";



# CERRAMOS EL BUCLE WHILE



}



# cerramos la conexión... y listo...



mysql_close($conexion)

# SALIMOS DE PHP y ponemos los botones de borrar /enviar desde HTML



?>



<td colspan=5 align=center><br><input type=submit value='Eliminar registros marcados'> <input type=reset value='Borrar el formulario'>



<!-- CERRAMOS EL FORMULARIO Y LA TABLA -->



</form></table>



<!-- LAS CASILLAS DE VERIFICACION PUEDEN MODIFICARSE DESDE EL TECLADO

SE PUEDE PASAR DE UNA A OTRA CON EL TABULAR

Y PARA ACTIVARLAS/DESACTIVARLAS PUEDES HACERLO CON EL RATON

O TAMBIEN PULSANDO LA BARRA ESPACIADORA

SI LA PULSAS UNA VEZ, SE ACTIVA, SI VUELVES A PULSARLA SE DESACTIVA



-->

</body>

</html>


SCRIPT:

<?

$base="ejemplos";



# establecemos la conexión con el servidor

$conexion=mysql_connect ("localhost","pepe","pepa");



#Seleccionamos la BASE DE DATOS en la que PRETENDEMOS TRABAJAR

mysql_select_db ($base, $conexion);



#recogemos del formulario la matriz borra[] que tiene como indices

#los dni de todos los registros de las bases de datos

# en los que la variable contenga el valor Si (los marcados)

# los registros no marcados (en el checkbox) no son transferidos

# por lo que TODOS LOS ELEMENTOS DEL ARRAY CORRESPONDEN A DNI'S ELEGIDOS PARA BORRAR



#leemos ese array completo usando el bucle foreach y

#recogemos el indice y el valor en $indice y $valor

foreach ($_POST['borra'] as $indice=>$valor){



#ejecutamos la instruccion DELETE filtrada por WHERE

# para que borre el registro en el que coincida DNI con el indice

mysql_query("DELETE FROM demo4 WHERE (DNI=$indice)",$conexion);

mysql_query("DELETE FROM demodat1 WHERE (DNI=$indice)",$conexion);

mysql_query("DELETE FROM demodat2 WHERE (DNI=$indice)",$conexion);

mysql_query("DELETE FROM demodat3 WHERE (DNI=$indice)",$conexion);



$num_borrados +=mysql_affected_rows();

# despues de borrar los registros en las cuatro tablas

# para asegurar la integridad referencial

# cerramos el bucle while

}

print ("Se han borrado ".$num_borrados." registros");



# cerramos la conexion

mysql_close($conexion);

?>


Guardar y recuperar bases de datos y o tablas

Aunque es perfectamente factible desarrollar scripts propios que permitan guardar y recuperar tanto las estructuras como los datos de una tabla ó de la base de datos completa, mencionaremos aquí una de las posibilidades más cómodas de hacerlos.

PhpMyAdmin es una magnifica herramienta para hacer y recuperar copias de seguridad.

Si abrimos esta utilidad http://localhost/myadmin/ podremos ver los dos enlaces que ves en la imagen –SQL y Exportar– que permiten importar y exportar tanto estructuras como datos y estructuras.



Al pulsar sobre Exportar nos aparecerá una página como esta:




donde podremos elegir una, varias o todas la tablas y que según la opciones elegidas nos permite exportar estructuras y/o datos, según las casillas de verificación que tengamos marcadas. Además nos permite elegir el formato en el que queremos guardar la copia –en nuestro caso elegiríamos SQL– y también según esté o no activada la casilla de verificación Enviar visualizar el fichero generado o guardarlo con el nombre que hayamos consignado en la caja de texto Plantilla del nombre del archivo.


Para restaurar datos y/o estructuras desde un fichero de seguridad creado mediante el proceso anterior usaríamos la opción SQL de la primera imagen. A través de ella accederíamos a una página cuyo contenido estamos visualizando en esta última imagen.

Bastaría pulsar en examinar, buscar el fichero de seguridad y pulsar continúe. MySQL se encargaría de restaurar –en la base de datos a la que pertenezcan– todas las tablas contenidas en esa copia.


Fuente:





Fuente:





No hay comentarios: