miércoles, 29 de abril de 2009

Descargar e Instalar software de modo automático en Windows.


Una de las tareas más farragosas a las que nos enfrentamos día si y día también los que nos dedicamos a esto del cacharreo con ordenadores de vecinos, amigos (más o menos conocidos) y demás familia es la instalación desde cero de equipos nuevos.

Desde hace algún tiempo la única condición que pongo para ello es la de la instalación de software libre -funciona exactamente igual que el "de pago" y no necesitas buscar serials, cracks,... y además todo es perfectamente legal. Esto puede ser un problema si el "amigo" de turno no está dispuesto a dejar su equipo en manos de un Linux ya que tendrás que prescindir de tu apt, synaptic o yast de turno para ponerte a bajar e instalar uno a uno cada programa necesario para su equipo.

Para solucionar este problema existen, desde luego, cds con las probablemente últimas versiones del software que casi deseemos -de alguno he hablado en alguna entrada anterior-, pero la posibilidad que os comento en esta entrada es la de bajaros un programa, que os permita seleccionar el software que deseáis instalar de modo que automáticamente os lo descargue y comience a instalarlo al finalizar de modo automático. Entre otras ventajas, tan sólo descargáis aquello que necesitáis y además completamente actualizado a la última versión disponible.

Me he encontrado con tres programas para hacer esta tarea:
  • AppSnap: a este programa pertenece la imagen que abre el artículo, si os decantáis por el recordad que tras instalarlo, lo primero que tenéis que hacer es pulsar el botón "Update DB" del menú, de modo que actualice el software disponible y los enlaces a las últimas versiones. Las ventajas que tiene con respecto al resto es que tiene una gran cantidad de software y además está categorizado, de modo que puedes buscar software para internet, actualizaciones de software ya instalado, herramientas de desarrollo, juegos,....
  • InstallPad: para su ejecución necesitas tener instalado Microsoft .NET framework 2.0. La ventaja que tiene es que puedes configurar mediante un fichero xml como el de la imagen que software quieres que aparezca y sus direcciones de descarga de un modo muy sencillo. El inconveniente es que, por defecto, trae muy pocas direcciones y además no están actualizadas.
Si en cualquier caso preferís bajaros un cd con todo el software para después instalarlo tranquilamente desde el mismo os copio a continuación un par de ellos:

Manual de PHP 79. MySQL: Tablas InnoDB

Tipos de tablas

Aunque en los temas anteriores no hemos hecho alusión a ello, MySQL permite usar diferentes tipos de tablas tales como:
  • ISAM
  • MyISAM
  • InnoDB
Las tablas ISAM son las de formato más antiguo. Están limitadas a tamaños que no superen los 4 gigas y no permite copiar tablas entre máquinas con distinto sistema operativo.

Las tablas MySAM son el resultado de la evolución de las anteriores, ya que resuelven el problema que planteaban las anteriores y son el formato por defecto de MySQL a partir de su versión 3.23.

Las tablas del tipo InnoDB tienen una estructura distinta que MyISAM, ya que utilizan un sólo archivo por tabla en ver de los tres habituales en los tipos anteriores.

Incorporan un par de ventajas importantes, ya que permiten realizar transacciones y definir reglas de integridad referencial.


Creación y uso de tablas InnoDB


La creación de tablas de este tipo no presenta ninguna dificultad añadida. El proceso es idéntico a las tablas habituales sin más que añadir Type=InnoDB después de cerrar el paréntesis de la sentencia de creación de la tabla.

Una vez creadas, las tablas InnoDB se comportan –a efectos de uso– exactamente igual que las que hemos venido utilizando en las páginas anteriores. No es preciso hacer ningún tipo de modificación en la sintaxis. Por tanto, es totalmente válido todo lo ya comentado respecto a: altas, modificaciones, consultas y bajas.

Las transacciones


Uno de los riesgos que se plantean en la gestión de bases de datos es que pueda producirse una interrupción del proceso mientras se está actualizando una o varias tablas. Pongamos como ejemplo el cobro de nuestra nómina. Son necesarias dos anotaciones simultáneas: ll cargo en la cuenta del Organismo pagador y el abono en nuestra cuenta bancaria. Si se interrumpiera fortuitamente el proceso en el intermedio de las dos operaciones podría darse la circunstancia de que apareciera registrado el pago sin que se llegaran a anotar los haberes en nuestra cuenta.

Las transacciones evitan este tipo de situaciones ya que los registros de los datos se registran de manera provisional y no toman carácter definitivo hasta que una instrucción confirme que esas anotaciones tienen carácter definitivo. Para ello, MySQL dispone de tres sentencias: BEGIN, COMMIT y ROLLBACK.

Sintaxis de las transacciones

Existen tres sentencias para gestionar las transacciones. Son las siguientes:

mysql_query("BEGIN",$c)

Su ejecución requiere que este activa la conexión $c con el servidor de base de datos e indica a MySQL que comienza una transacción.

Todas las sentencias que se ejecuten a partir de ella tendrán carácter provisional y no se ejecutarán de forma efectiva hasta que encuentre una sentencia de finalización.

mysql_query("ROLLBACK",$c)

Mediante esta sentencia advertimos a MySQL que finaliza la transacción pero que no debe hacerse efectiva ninguna de las modificaciones incluidas en ella.

mysql_query("COMMIT",$c)

Esta sentencia advierte a MySQL que ha finalizado la transacción y que debe hacer efectivos todos los cambios incluidos en ella.


Precauciones a tener en cuenta

Cuando se utilizan campos autoincrementales en tablas InnoDB los contadores se van incrementando al añadir registros (incluso de forma provisional) con lo cual si se aborta la inclusión con un ROLLBACK ese contador mantiene el incremento y en inserciones posteriores partirá de ese valor acumulado.

Por ejemplo. Si partimos de una tabla vacía y hacemos una transacción de dos registros (número 1 y número 2 en el campo autoincremental) y la finalizamos con ROLLBACK, no se insertarán pero en una inserción posterior el contador autoincremental comenzará a partir del valor 2.

MySQL anuncia que a partir de la versión 5.0.3 se incluirá una nueva sentencia para permitir que se puedan renumerar los campos autoincrementales.

Elementos necesarios para la integridad referencial

La integridad referencial ha de establecerse siempre entre dos tablas. Una de ellas ha de comportarse como tabla principal (suele llamarse tabla padre y la otra sería la tabla vinculada ó tabla hijo.

Es imprescindible:
  • Que la tabla principal tenga un índice primario (PRIMARY KEY)
  • Que la tabla vinculada tenga un índice (no es necesario que sea ni único ni primario) asociado a campos de tipo idéntico a los que se usen para índice de la tabla principal. -es decir, puede ser simplemente INDEX.
  • Si observas el código fuente del ejemplo que tienes a la derecha podrás observar que utilizamos el número del DNI (único para alumno) como elemento de vinculación de la tabla de datos personales con la que incluye las direcciones.
Borrado de tablas vinculadas

Si pretendemos eliminar una tabla principal recibiremos un mensaje de error tal como puedes ver si ejecutas este ejemplo cuyo código fuente tienes aquí. cómo es lógico, antes de ejecutarlo habrás de tener creada la tabla cuyo código fuente tienes a la derecha.

Las tablas vinculadas si permiten el borrado y una vez que éstas ya han sido eliminadas (o quitada la vinculación) ya podrán borrarse sin problemas las tablas principales. Si ejecutas este ejemplo podrás observar que borramos ambas tablas siguiendo el orden que permite hacerlo. Primero se borra la vinculada y luego la principal. Este es el código fuente del script:


<?

$base="ejemplos";

$tabla="principal";

$tabla1="vinculada";

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

mysql_select_db ($base, $c);

# borramos primero la tabla vinculada

if(mysql_query("DROP TABLE $tabla1",$c)){

echo "<h2> Tabla $tabla1 borrada con EXITO </h2><br>";

}else{

echo "<h2> La tabla $tabla1 NO HA PODIDO BORRARSE<br>";

echo "Se ha producido un error nº: ".mysql_errno ($c)."<br>";

echo "que es el siguiente: ".mysql_error ($c)."<br>";

};

# ahora ya podremos hacer lo mismo con la principal

if(mysql_query("DROP TABLE $tabla",$c)){

echo "<h2> Tabla $tabla borrada con EXITO </h2><br>";

}else{

echo "<h2> La tabla $tabla NO HA PODIDO BORRARSE<br>";

echo "Se ha producido un error nº: ".mysql_errno ($c)."<br>";

echo "que es el siguiente: ".mysql_error ($c)."<br>";

};

mysql_close();

?>



¡Cuidado!

Si has borrado las tablas con los ejemplos anteriores no olvides crearlas de nuevo para poder visualizar los ejemplos siguientes.


Modificación o borrado de campos vinculados

Las sentencias MySQL que deban modificar o eliminar campos utilizados para establecer vínculos entre tablas requieren de un parámetro especial (CONSTRAINT) -puede ser distinto en cada una de las tablas- que es necesario conocer previamente.

La forma de visualizarlo es ejecutar la sentencia: SHOW CREATE TABLE nombre tabla que devuelve como resultado un array asociativo con dos índices. Uno de ellos -llamado Table- que contiene el nombre de la tabla y el otro -Create Table- que contiene la estructura con la que ha sido creada la tabla pero incluyendo el parámetro CONSTRAINT seguido de su valor. Ese valor es precisamente el que necesitamos para hacer modificaciones en los campos asociados de las tablas vinculadas.

Pulsando en este enlace cuyo código fuente tienes aquí:

<?

$base="ejemplos";

$tabla="principal";

$tabla1="vinculada";

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

mysql_select_db ($base, $c);



$resultado=mysql_query( "SHOW CREATE TABLE $tabla1",$c);

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

foreach ($registro as $c=>$v){

Print "<i>Indice</i><b>: ".$c." </b><i>Valor</i>: ".$v."<br>";

}



}

mysql_close();

?>



podrás visualizar el resultado de la ejecución de esa sentencia.

Conocido el valor de parámetro anterior el proceso de borrado del vínculo actual requiere la siguiente sintaxis:

ALTER TABLE nombre de la tabla DROP FOREIGN KEY parametro

Cuando se trata de añadir un nuevo vínculo con una tabla principal habremos de utilizar la siguiente sentencia:

ALTER TABLE nombre de la tabla ADD [CONSTRAINT parametro] FOREIGN KEY parametro REFERENCES tabla principal(clave primaria)

El parámetro CONSTRAIT (encerrado en corchetes en el párrafo anterior) es OPCIONAL y solo habría de utilzarse en el caso de que existiera ya una vinculación previa de esa tabla.


La función preg_match

En el ejemplo de la derecha utilizamos esta función cuya sintaxis es la siguiente:
preg_match( pat, cad, coin )

donde pat es un patrón de búsqueda, cad es la cadena que la han de realizarse las búsquedas y coin es un arroay que recoge todas las coincidencias encontradas en la cadena.

El patrón de búsqueda que hemos utilizado en el ejemplo
/CONSTRAINT.*FOREIGN KEY/ debe interpretarse de la siguiente forma. Los caracteres / indican el comienzo y el final del patrón, el . indica que entre CONSTRAIT y FOREING se permite cualquer carácter para admitir la coincidencia y, además, * indica que ese caracter cualquier puede repetirse cero o más veces.

¡Cuidado!

Es posible que el script del final te de un error como consecuencia de que hemos podido modificar campos en los ejemplos anteriores. Si eso ocurre, borra aquí las tablas y genéralas de nuevo pulsando aquí.


¡Cuidado!

Los resultados que obtengas el ejecutar los ejemplos de borrado y modificación de datos pueden arrojar resultados distintos según los contenidos de las tablas que, a su vez, serán consecuencia de los ejemplos que hayas ejecutado anteriormente y de la secuencia de los mismos. Siempre puedes volver a las condiciones iniciales de los enlaces de la advertencia anterior.


Opciones adicionaes de FOREIGN KEY


La claúsula FOREIGN KEY permite añadirte -detrás de la definición ya comentada y sin poner coma separándola de ella- los parámetros ON DELETE y ON UPDATE en las que se permite especificar una de las siguientes opciones:

ON DELETE RESTRICT
Esta condición (es la condición por defecto de MySQL y no es preciso escribirla) indica a MySQL que interrumpa el proeceso de borrado y de un mensaje de error cuando se intente borrar un registro de la tabla principal cuando en la tabla vinculada existan registros asociados al valor que se pretende borrar.

ON DELETE NO ACTION
Es un sinónimo de la anterior.

ON DELETE CASCADE
Cuando se especifica esta opción, al borrar un registro de la tabla principal se borrarán de forma automática todos los de la tabla vinculada que estuvieran asociados al valor de la clave foránea que se trata de borrar. Con ello se conseguiría una actualización automática de la segunda tabla y se mantendría la identidad referencial.

ON DELETE SET NULL
Con esta opción, al borrar el registro de la tabla principal no se borrarían los que tuviera asociados la tabla secundaria pero tomarían valor NULL todos los índices de ella coincidentes con la clave primaria de la tabla principal.

Para el caso de ON UPDATE las opciones son estas:

ON UPDATE RESTRICT
ON UPDATE CASCADE
ON UPDATE SET NULL

Su comportamiento es idéntico a sus homónimas del caso anterior.

¡Cuidado!

El uso de la opción SET NULL requiere que el campo indicado en FOREIGN KEY esté permita valores nulos. Si está definido con flag NOT NULL (como ocurre en los ejemplos que tienes al margen) daría un mensaje de error.


¡Cuidado!

Al incluir ON DELETE y ON UPTADE (si se incluyen ambas) han de hacerse por este mismo orden.
Si se cambiara este orden daría un mensaje de error y no se ejecutarían.


Creación de una tabla InnoDB


La creación de tablas tipo InnoDB requiere una de estas dos sentencias:


CREATE TABLE IF NOT EXISTS tabla (campo1, campo2,... ) Type=InnoDB


CREATE TABLE tabla (campo1, campo2,... ) Type=InnoDB


Este script crear una tabla InnoDB con idénticos campos a los utilizados en el caso de la tabla demo4 con la que hemos venido trabajando hasta ahora. La sintaxis, muy similar a la utilizada allí es esta:


$base="ejemplos";
$tabla="demoINNO";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);

$crear="CREATE TABLE $tabla (";
$crear.="Contador TINYINT(8) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,";
$crear.="DNI CHAR(8) NOT NULL, ";
$crear.="Nombre VARCHAR (20) NOT NULL, ";
$crear.="Apellido1 VARCHAR (15) not null, ";
$crear.="Apellido2 VARCHAR (15) not null, ";
$crear.="Nacimiento DATE DEFAULT '1970-12-21', ";
$crear.="Hora TIME DEFAULT '00:00:00', ";
$crear.="Sexo Enum('M','F') DEFAULT 'M' not null, ";
$crear.="Fumador CHAR(0) , ";
$crear.="Idiomas SET(' Castellano',' Francés','Inglés',
' Alemán',' Búlgaro',' Chino'), ";
$crear.=" PRIMARY KEY(DNI), ";
$crear.=" UNIQUE auto (Contador)";
$crear.=")";
# esta es la única diferencia con el proceso de
# creación de tablas MyISAM
$crear.=" Type=InnoDB";

if(mysql_query ($crear ,$c)) {
echo "<h2> Tabla $tabla creada con EXITO </h2><br>";
}else{
echo "<h2> La tabla $tabla NO HA PODIDO CREARSE ";
# echo mysql_error ($c)."<br>";
$numerror=mysql_errno ($c);
if ($numerror==1050){echo "porque YA EXISTE</h2>";}
};
mysql_close($c);
?>

Crear tabla InnoDB




Bajo Windows, al crear una base de datos o tabla InnoDB el nombre de la misma aparecerá en minúsculas independientemente de la sintaxis que hayamos utilizado en su creación.

Si observas el ejemplo anterior, hemos puesto demoINNO como nombre de la tabla. Sin embargo, si miras el directorio c:\mysql verás que aparece el fichero demoinno.frm con minúsculas.



Las primeras transacciones

<?
$base="ejemplos";
# escribimos el nombre de la tabla en MINUSCULAS
# para asegurar la compatibilidad entre plataformas
$tabla="demoinno";
$conexion=mysql_connect("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
# insertamos la sentencia BEGIN para indicar el comienzo
# de una transacción
mysql_query("BEGIN",$conexion);
/* hasta que no aparezca una sentencia que finalice la transacción
(ROLLBACK ó COMMIT) las modificaciones en la tabla serán registradas
de forma "provisional") */
mysql_query("INSERT $tabla (DNI,Nombre,Apellido1,Apellido2,
Nacimiento,Sexo,Hora,Fumador,Idiomas)
VALUES
('111111','Alvaro','Alonso','Azcárate','1954-11-23',
'M','16:24:52',NULL,3)",$conexion);
if (mysql_errno($conexion)==0){
echo "Registro AÑADIDO<br>";
}else{
if (mysql_errno($conexion)==1062){
echo "No ha podido añadirse el registro <br>";
echo "Ya existe un registro con este DNI<br>";
}else{
$numerror=mysql_errno($conexion);
$descrerror=mysql_error($conexion);
echo "Se ha producido un error nº $numerror<br>";
echo "<br>que corresponde a: $descrerror<br>";
}
}
# indicamos el final de la transacción, en este caso con ROLLBACK
# por lo tanto el registro con DNI 111111 no será insertado en la tabla
mysql_query("ROLLBACK",$conexion);
# incluyamos una nueva transacción
mysql_query("BEGIN",$conexion);
mysql_query("INSERT $tabla (DNI,Nombre,Apellido1,Apellido2,
Nacimiento,Sexo,Hora,Fumador,Idiomas)
VALUES
('222222','Genoveva','Zarabozo','Zitrón','1964-01-14',
'F','16:18:20',NULL,2)",$conexion);
if (mysql_errno($conexion)==0){
echo "Registro AÑADIDO";
}else{
if (mysql_errno($conexion)==1062){
echo "No ha podido añadirse el registro <br>";
echo "Ya existe un registro con este DNI";
}else{
$numerror=mysql_errno($conexion);
$descrerror=mysql_error($conexion);
echo "Se ha producido un error nº $numerror";
echo "<br>que corresponde a: $descrerror";
}
}
# indicamos el final de la transacción, en este caso con COMMIT
# por lo tanto el registro con DNI 222222 si será insertado en la tabla
mysql_query("COMMIT",$conexion);
# leamos el contenido de la tabla para ver el resultado
$resultado= mysql_query("SELECT * FROM $tabla" ,$conexion);
print "<br>Lectura de la tabla depués del commit<br>";
while ($registro = mysql_fetch_row($resultado)){
foreach($registro as $clave){
echo $clave,"<br>";
}
}
mysql_close();
?>


ejemplo236.php

Ejecutar el ejemplo


Integridad referencial en tablas InnoDB


Cuando se trabaja con varias tablas que tienen algún tipo de vínculo resulta interesante disponer de mecanismos que protejan o impidan acciones no deseadas. Supongamos, como veremos en los ejemplos posteriores que pretendemos utilizar una tabla con datos de alumnos y otra tabla distinta para las calificaciones de esos alumnos. Si no tomamos ninguna precaución (bien sea mediante los script o mediante el diseño de las tablas) podría darse la circunstancia de que incluyéramos calificaciones a alumnos inexistentes, en materias de las que no están matriculados, etcétera. También podría darse la circunstancia de que diéramos de baja a un alumno pero que se mantuvieran las calificaciones vinculadas a él. Todas estas circunstancias suelen producir efectos indeseados y las tablas InnoDB pueden ser diseñadas para prever este tipo de situaciones.


Sintaxis para la vinculación de tablas


Los vínculos entre tablas suelen establecer en el momento de la creación de la tabla vinculada.


CREATE TABLE tabla (campo1, campo2,...

KEY nombre (campo de vinculacion ),

FOREIGN KEY (campo de vinculacion)
REFERENCES nombre_de la tabla principal (Indice primario de la tabla principal)

) Type=InnoDB

si el campo nombre no fuera la clave principal tendríamos que emplear, por ejemplo

CREATE TABLE tabla (campo1, campo2,...

PRIMARY KEY nombre (campos clave de la tabla),

INDEX nombre (campo de vinculacion ),

FOREIGN KEY (campo de vinculacion)
REFERENCES nombre_de la tabla principal (Indice primario de la tabla principal)

) Type=InnoDB

donde el campo de vinculacion ha de ser un índice (no es necesario que sea PRIMARY KEY ni UNIQUE) y donde Indice primario de la tabla principal ha de ser un índice primario (PRIMARY KEY) de la tabla principal. Debe haber plena coincidencia (tanto en tipos como contenidos) entre ambos índices.

<?
$base="ejemplos";
$tabla1="principal";
$tabla2="vinculada";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
# creación de la tabla principal type InnoDB
$crear="CREATE TABLE IF NOT EXISTS $tabla1 (";
$crear.="DNI CHAR(8) NOT NULL, ";
$crear.="Nombre VARCHAR (20) NOT NULL, ";
$crear.="Apellido1 VARCHAR (15) not null, ";
$crear.="Apellido2 VARCHAR (15) not null, ";
# el indice primario es imprescindible. Recuerda que debe
# estar definido sobre campos NO NULOS
$crear.=" PRIMARY KEY(DNI) ";
$crear.=")";
$crear.=" Type=InnoDB";
# creamos la tabla principal comprobando el resultado
if(@mysql_query ($crear ,$c)){
print "La tabla ".$tabla1." ha sido creada<br>";
}else{
print "No se ha creado ".$tabla1." ha habido un error<br>";
}
# crearemos la tabla vinculada
$crear="CREATE TABLE IF NOT EXISTS $tabla2 (";
$crear.="IDENTIDAD CHAR(8) NOT NULL, ";
$crear.="calle VARCHAR (20), ";
$crear.="poblacion VARCHAR (20), ";
$crear.="distrito VARCHAR(5), ";
# creamos el índice (lo llamamos asociador) para la vinculación
# en este caso no será ni primario ni único
# Observa que el campo IDENTIDAD de esta tabla CHAR(8)
# es idéntico al campo DNI de la tabla principal
$crear.=" KEY asociador(IDENTIDAD), ";
#establecemos la vinculación de ambos índices
$crear.=" FOREIGN KEY (IDENTIDAD) REFERENCES $tabla1(DNI) ";
$crear.=") TYPE = INNODB";
# creamos (y comprobamos la creación) la tabla vinculada
if(@mysql_query ($crear ,$c)){
print "La tabla ".$tabla2." ha sido creada<br>";
}else{
print "No se ha creado ".$tabla2." ha habido un error<br>";
}
mysql_close();
?>


ejemplo239.php

Crear tablas vinculadas


Modificación de estructuras


La modificación de estructuras en tablas vinculadas puede hacerse de forma idéntica a la estudiada para los casos generales de MySQL siempre que esas modificaciones no afecten a los campos mediante los que se establecen las vinculaciones entre tablas.


Aquí tienes un ejemplo en se borran y añaden campos en ambas tablas. Como puedes ver la sintaxis es exactamente la misma que utilizamos en temas anteriores.

<?
$base="ejemplos";
$tabla="principal";
$tabla1="vinculada";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);

if(mysql_query("ALTER TABLE $tabla ADD Segundo_Apellido VARCHAR(40)",$c)){
print "Sea ha creado el nuevo campo en ".$tabla."<br>";
}
if(mysql_query("ALTER TABLE $tabla DROP Apellido2",$c)){
print "Sea ha borrado el campo Apellido 2 en ".$tabla."<br>";
}

if(mysql_query("ALTER TABLE $tabla1 ADD DP VARCHAR(5)",$c)){
print "Sea ha creado el nuevo campo en ".$tabla1."<br>";
}
if(mysql_query("ALTER TABLE $tabla1 DROP distrito",$c)){
print "Sea ha borrado el campo distrito en ".$tabla1."<br>";
}

mysql_close();
?>


ejemplo242.php

ejecutar el ejemplo



En este otro ejemplo determinaremos el valor de CONSTRAINT y modificaremos campos asociados de la tabla vinculada.


$base="ejemplos";
$tabla="vinculada";
$tabla1="principal";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
$resultado=mysql_query( "SHOW CREATE TABLE $tabla",$c);
$v=mysql_fetch_array($resultado);
# extreamos de Create Table la cadena que empiza por CONSTRAINT
# y que acaba por FOREING KEY lo guardamos en el array $coin
preg_match ('/CONSTRAINT.*FOREIGN KEY/', $v['Create Table'], $coin);
# extraemos el parametro quitando el CONSTRAINT que lleva delante
# y el FOREIGN KEY que lleva al final
$para=str_replace("FOREIGN KEY",'',str_replace("CONSTRAINT",'',$coin[0]));
print "El valor de CONSTRAINT es: ".$para."&ltbr>";
# eliminamos el vinculo con la clave externa incluyendo en la sentancia
# el valor del parametro obtenido el proceso anterior
if(mysql_query("ALTER TABLE $tabla DROP FOREIGN KEY $para",$c)){
print "Se ha realizado con éxito el borrado del vínculo&ltbr>";
}
# añadimos el nuevo vínculo (en este caso rehacemos el anterior
# pero el proceso es idéntico)
if(mysql_query("ALTER TABLE $tabla ADD CONSTRAINT $para
FOREIGN KEY(IDENTIDAD) REFERENCES $tabla1(DNI)",$c)){
print "Se ha reestablecido con éxito vínculo&ltbr>";
}

mysql_close();
?>


ejemplo244.php

ejecutar el ejemplo


Añadir registros a la tabla vinculada


Si ejecutas este ejemplo habiendo seguido la secuencia de estos materiales verás que se produce un error nº 1216. Es lógico que así sea porque estamos intentando añadir un registro a la tabla vinculada y ello requeriría que en el campo DNI de la tabla principal existiera un registro con un valor igual al que pretendemos introducir en la tabla vinculada.



ejemplo245.php

Ver script

Insertar en tabla vinculada


Añadiremos un registro a la tabla principal con el DNI anterior:

ejemplo245.php

Ver script

ejemplo246.php

Insertar en tabla principal


y ahora ya podremos ejecutar -sin errores- el script que inserta datos en la tabla vinculada. Podremos ejecutar aquel script tantas veces como queramos ya que -el campo IDENTIDAD está definido como KEY y por tanto permite duplicados- no hemos establecido la condición de índice PRIMARIO ó UNICO.


Borrar o modificar registros en la tabla principal


Sin intentamos borrar un registro de la tabla principal mediante un script como el que tienes en este ejemplo verás que se produce un error nº 1217 advirtiéndonos de que no se realiza el borrado porque existen registros en la tabla vinculada con valores asociados al índice del campo que pretendemos borrar y, de permitir hacerlo, se rompería la integridad referencial ya que quedarían registros huérfanos en la tabla vinculada.



ejemplo247.php

Ver script

ejemplo247.php

Borrar en tabla principal


Sin tratamos de modificar un registro de la tabla principal y la modificación afecta al índice que realiza la asociación con la tabla (o tablas) vinculadas se produciría -por las mismas razones y en las mismas circunstancias- un error nº 1217 que impediría la modificación.

ejemplo248.php

Ver script

ejemplo248.php

Modificar DNI en tabla principal


Si -al tratar de borrar o modificar un registro de la tabla principal– no existieran en la tabla (o tablas vinculadas) registros asociados con él, el proceso de modificación se realizaría sin ningún problema y sin dar ningún mensaje de error o advertencia.


Automatización de procesos


Creamos dos tablas idénticas a las anteriores incluyendo algunos datos en ellas.

<?
$base="ejemplos";
$tabla1="principal1";
$tabla2="vinculada1";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
# creación de la tabla principal type InnoDB
$crear="CREATE TABLE IF NOT EXISTS $tabla1 (";
$crear.="DNI CHAR(8) NOT NULL, ";
$crear.="Nombre VARCHAR (20) NOT NULL, ";
$crear.="Apellido1 VARCHAR (15) not null, ";
$crear.="Apellido2 VARCHAR (15) not null, ";
$crear.=" PRIMARY KEY(DNI) ";
$crear.=")";
$crear.=" Type=InnoDB";
# creamos la tabla principal comprobando el resultado
if(@mysql_query ($crear ,$c)){
print "La tabla ".$tabla1." ha sido creada<br>";
}else{
print "No se ha creado ".$tabla1." ha habido un error<br>";
}
# crearemos la tabla vinculada
$crear="CREATE TABLE IF NOT EXISTS $tabla2 (";
$crear.="IDENTIDAD CHAR(8) NOT NULL, ";
$crear.="calle VARCHAR (20), ";
$crear.="poblacion VARCHAR (20), ";
$crear.="distrito VARCHAR(5), ";
#creamos la tabla vinculada las opciones de DELETE y UPDATE
$crear.=" KEY asociador(IDENTIDAD), ";
#establecemos la vinculación de ambos índices
$crear.=" FOREIGN KEY (IDENTIDAD) REFERENCES $tabla1(DNI) ";
$crear.=" ON DELETE CASCADE ";
$crear.=" ON UPDATE CASCADE ";
$crear.=") TYPE = INNODB";
# creamos (y comprobamos la creación) la tabla vinculada
if(@mysql_query ($crear ,$c)){
print "La tabla ".$tabla2." ha sido creada<br>";
}else{
print "No se ha creado ".$tabla2." ha habido un error<br>";
}
# añadimos registros a la tabla principa1
mysql_query("INSERT $tabla1 (DNI,Nombre,Apellido1,Apellido2)
VALUES ('111111','Robustiano','Iglesias','Pérez')",$c);
mysql_query("INSERT $tabla1 (DNI,Nombre,Apellido1,Apellido2)
VALUES ('222222','Ambrosio','Morales','Gómez')",$c);
# añadimos registros a la tabla vinculada1
mysql_query("INSERT $tabla2 (IDENTIDAD,calle,poblacion,distrito)
VALUES ('111111','Calle Asturias,3','Oviedo','33001')",$c);
mysql_query("INSERT $tabla2 (IDENTIDAD,calle,poblacion,distrito)
VALUES ('111111','Calle Palencia,3','Logroño','78541')",$c);
mysql_query("INSERT $tabla2 (IDENTIDAD,calle,poblacion,distrito)
VALUES ('222222','Calle Anunciación,3','Algeciras','21541')",$c);
mysql_close();
?>


ejemplo249.php

Crear tablas y datos


ejemplo250.php

Ver contenidos de tablas

php250.php

Ver codigo fuente



Modificar registros en cascada

<?
$base="ejemplos";
$tabla="principal1";
$conexion=mysql_connect("localhost","pepe","pepa");
mysql_select_db($base,$conexion);
# modificamos un registro
mysql_query("UPDATE $tabla SET DNI='123456' WHERE DNI='111111'",$conexion);
# borramos un registro
mysql_query("DELETE FROM $tabla WHERE (DNI='222222')",$conexion);
if (mysql_errno($conexion)==0){echo "<h2>Tablas actualizadas</b></H2>";
}else{
print "Ha habido un error al actualizar";
}
mysql_close();
?>


ejemplo251.php

Actualizar en cascada


ejemplo250.php

Ver contenido de la tabla


Para que puedas retornar a las condiciones iniciales, desde este enlace podrás borrar las tablas creadas para actualización en cascada. De esta forma podrás volver a crearlas, cuando desees, en las condiciones iniciales.




Fuente:




Manual de PHP 78. MySQL: Imágenes en Tablas

Peculiaridades de las tablas

Las tablas que han de contener imágenes deben tener campos del tipo BLOB, MEDIUMBLOB o LONGBLOB, pudiendo elegir aquel de ellos que más se adecue al tamaño, en bytes, de las imágenes que se desean guardar en la tabla.

Por si te has olvidado de los tipos de campos, aquí tienes un enlace para recordarlos.

En el ejemplo la hemos creado con un campo BLOB insertando también campos para recoger su nombre, su tamaño (en bytes), su formato (el tipo de fichero transferido) así como un campo autoincremental.


Desde este enlace -has de tener activo el servidor MySQL- podrás crear la tabla fotos e insertar automáticamente algunas imágenes de ejemplo.


Transferencia de la imagen

El formulario para realizar la transferencia de la imagen no tiene particularidades. Es un formulario como los de toda la vida. Lo único reseñable sería incluir un campo oculto en el que pudiera especificarse una restricción en cuanto al tamaño máximo permitido para cada imagen y que debe estar acorde con el tipo de campo utilizado en la tabla.


Comprobación del tipo de imagen

Al transferir imágenes jpg ó png el type MIME que recibía el servidor es distinto según el navegador que se utilice para hacer la transferencia.

Aquí más abajo, en el código fuente del script que actualiza la base de datos, tienes los nombres de esos tipos asociados a los navegadores más usuales.

Hay otro aspecto a tener en cuenta. Esa discriminación de tipos se plantea únicamente cuando Apache recibe una transferencia. Cuando se visualiza un contenido las cabeceras tipo de contenido (header("content-type: xx")) pueden ser las mismas para todos los navegadores. Esa es la razón por la que a la hora de incluir el formato en la tabla utilizamos image/jpg, image/gif o image/png.


¿Cómo guardamos la imagen?

La información recibida a través del formulario requiere un ligero retoque antes de incluirla en le campo BLOB de la tabla. Esa reconversión requiere abrir la imagen en modo binario (rb) -parece que solo en el caso de Windows– leer el fichero completo y añadirle \ antes de las comillas mediante addslashes.

Una vez hecho el retoque ya puede guardarse sin más problema.


PNG con transparencias en Internet Explorer

Internet Explorer no permite visualizar de forma automática las transparencias de las imágenes con formato png. Existen en la red algunos recursos que permiten solventar ese problema.

Hemos elegido uno de ellos –pngfix.js- que puedes ver en este enlace.

Se trata de un fichero JavaScript que basta incluir en la cabecera HMTL de la página de la forma que ves en el ejemplo de la parte derecha. Cuando un navegador IE es detectado se ejecuta una función contenida en ese fichero que analiza la página, busca imágenes con extensión png y les aplica la transparencia adecuada.

Por esa razón, es probable que inicialmente (al cargar la página) se visualice la imagen opaca y que, posteriormente, adquiera la transparencia.


Ver las imágenes

La lectura de una imagen utiliza solo dos instrucciones. Incluir la cabecera Header en el que se indica el tipo de contenido (el famoso nombre MIME de la imagen) y luego imprimir el contenido del campo.

Pero (por aquello de que header debe ir incluida en el script antes que cualquier otra salida) si pretendemos incluir en una página algo más que una imagen tendremos que invocar esas dos funciones, de forma independiente, para cada una de ellas.

Por esa razón, en el ejemplo que tienes al final, al desarrollar el ejemplo que permite visualizar todas las imágenes de la tabla hemos tenido que incluir un script que va leyendo la tabla que con contiene las imágenes para extraer los campos informativos y a la hora de ver la imagen hemos de recurrir a la misma técnica que se utilizaba para ver las imágenes dinámicas.

Es decir, poner una etiqueta de imagen de las de HTML pero -en vez de escribir el nombre de la imagen- poniendo incluyendo como nombre el del script que las visualiza y pasándole el número (valor del campo autoincremental) de la imagen que pretendí visualizar.


El problema de los PNG en IE

El JavaScript que asigna la transparencia a las imágenes en formato png las identifica buscando la coincidencia de los tres últimos caracteres del nombre de la imagen con la extensión png.

Cuando se trata de imágenes dinámicas el nombre de la imagen coinciden con el nombre de la llamada al script que se utiliza para su visualización. Por eso, para advertir a JavaScript de que se trata de una imagen png hemos incluido el condicional que puedes ver en el ejemplo. De esa forma, cuando se trata de una imagen en este formato incluimos en la petición una variable con el valor png de forma que pueda ser reconocida por pngfix.js y aplicada la transparencia requerida.


Creación de una tabla ejemplo


Lo primero de todo será disponer de una tabla en la que puedan guardarse imágenes. Aquí tienes un ejemplo.

<?
#el nombre de la tabla
$base="ejemplos";
#definimos otra variable con el NOMBRE QUE QUEREMOS DAR A LA TABLA
$tabla="fotos";
# establecemos la conexión con el servidor
$conexion=mysql_connect ("localhost","pepe","pepa");
#Seleccionamos la BASE DE DATOS en la que PRETENDEMOS CREAR LA TABLA
mysql_select_db ($base, $conexion);

$crear="CREATE TABLE IF NOT EXISTS $tabla (";
$crear.="num_ident INT(10) unsigned NOT NULL AUTO_INCREMENT,";
$crear.="imagen BLOB NOT NULL, ";
$crear.="nombre VARCHAR(255) NOT NULL DEFAULT '',";
$crear.="tamano VARCHAR(15) NOT NULL DEFAULT '',";
$crear.="formato VARCHAR(10) NOT NULL DEFAULT '',";
$crear.="PRIMARY KEY (num_ident))";

#Creamos la cadena, comprobamos si esa instrucción devuelve
# VERDADERO o FALSO
# y dependiendo de ellos insertamos el mensaje de exito o fracaso

if(mysql_db_query ($base,$crear ,$conexion)) {
echo "<h2> Tabla $tabla creada con EXITO </h2><br>";
}else{
echo "<h2> La tabla $tabla NO HA PODIDO CREARSE</h2><br>";
};

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

mysql_close($conexion);
?>

Formulario para la transferencia de las imágenes

<FORM ENCTYPE="multipart/form-data" ACTION="ejemplo211.php" METHOD="post">
#con este input "oculto" establecemos el limite máximo
# del tamaño del fichero a transferir. En este ejemplo 65.000 bytes
<INPUT type="hidden" name="lim_tamano" value="65000">
<p><b>Selecciona la imagen a transferir<b><br>
<INPUT type="file" name="foto"><br>
<p><b>Título la imagen<b><br>
<INPUT type="text" name="titulo"><br></p>
<p><INPUT type="submit" name="enviar" value="Aceptar"></p>
</FORM>


ejemplo212.php

Ejemplo de transferencia de imagen


Script para actualizar la base de datos

<?
$foto_name= $_FILES['foto']['name'];
$foto_size= $_FILES['foto']['size'];
$foto_type= $_FILES['foto']['type'];
$foto_temporal= $_FILES['foto']['tmp_name'];
$lim_tamano= $_POST['lim_tamano'];
$foto_titulo= $_POST['titulo'];
/* limitamos los formatos de imagen admitidos a:
png que segun del navegador que ulicemos puede ser:
en IE image/x-png en Firefox y Mozilla image/png
jpg que puede tener como tipo
en IE image/pjpeg en Firefox y Mozilla image/jpeg
gif que tiene como tipo image/gif en todos los navegadores
Mira los comentarios al margen sobre la variable $extensión */
if ($foto_type=="image/x-png" OR $foto_type=="image/png"){
$extension="image/png";
}
if ($foto_type=="image/pjpeg" OR $foto_type=="image/jpeg"){
$extension="image/jpeg";
}
if ($foto_type=="image/gif" OR $foto_type=="image/gif"){
$extension="image/gif";
}
# condicionamos la inserción a que la foto tenga nombre,
# un tamaño distinto de cero y menor de límite establecido
# en el formulario y que la variable extensión sea no nula

if ($foto_name != "" AND $foto_size != 0
AND $foto_titulo !='' AND
$foto_size<=$lim_tamano AND $extension !=''){
/*reconversion de la imagen para meter en la tabla
abrimos el fichero temporal en modo
lectura "r" binaria"b"*/
$f1= fopen($foto_temporal,"rb");
#leemos el fichero completo limitando
# la lectura al tamaño de fichero
$foto_reconvertida = fread($f1, $foto_size);
#anteponemos \ a las comillas que pudiera contener el fichero
# para evitar que sean interpretadas como final de cadena
$foto_reconvertida=addslashes($foto_reconvertida);
# abrimos la base de datos y escribimos las intrucciones de inserción
# en el campo BLOB insertaremos la foto_reconvertida
$base="ejemplos";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
$meter="INSERT INTO ".$tabla;
$meter .=" (num_ident, imagen, nombre, tamano, formato) ";
$meter .=" VALUES('','$foto_reconvertida','$foto_titulo',";
$meter .= "$foto_size, '$extension')";
if (@mysql_query($meter,$conexion)){
print "Foto guardada en la tabla";
}else{
print "Ha habido un error al guardar la foto";
}
}else{
echo "<h2>No ha podido transferirse el fichero</h2>";
}
mysql_close();
?>

Script para leer la base de datos

<html>
<head>
<!-- al margen te comentamos la razón por la que -->
<!-- se incluyen estas líneas en rojo -->
<!--[if IE ]>
<script type="text/javascript" src="pngfix.js"></script>
<![endif]-->
</head>
<body>
<?
$base="ejemplos";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
$sacar = "SELECT * FROM ".$tabla;
$resultado = mysql_query($sacar,$conexion);
while ($registro = mysql_fetch_array($resultado)){
print "<center>Titulo de la imagen: ".$registro['nombre']."<br>";
/* la inclusión de este condicional obedece a los problemas que plantea
la visualización de las transparencias
de las imágenes png en Internet Explorer.
Al margen justificamos las razones de su inclusión */
if($registro['formato']=="image/png"){
print "<img src='ver_foto.php?n=".$registro['num_ident']."&v=png'><br>";
}else{
print "<img src='ver_foto.php?n=".$registro['num_ident']."'><br>";
}
print "Tamaño de la imagen: ".$registro['tamano']." bytes
</center>";

}
mysql_close();
?>
</body>
</html>

Script para leer imágenes de la base datos

<?
$numero=$_REQUEST['n'];
$base="ejemplos";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
$sacar = "SELECT * FROM ".$tabla." WHERE (num_ident=$numero)" ;
$resultado = mysql_query($sacar,$conexion);
while ($registro = mysql_fetch_array($resultado)){
$tipo_foto=$registro['formato'];
header("Content-type: $tipo_foto");
echo $registro['imagen'];
}
mysql_close();
?>


ejemplo209.php
Ver imágenes guardadas



Fuente:




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: