PHP+SQLGuía del curso 12. El lenguaje SQL. Una base de datos relacional es un programa capaz de almacenar grandes cantidades de información y de ofrecerla de manera rápida con capacidad para combinar y ordenar los datos, ajustándose a los requerimientos del usuario. SQL es el acrónimo de “Structured Query Language” (Lenguaje estructurado de consultas). Este es un estándar que utilizan las bases de datos relacionales para insertar, actualizar, eliminar y recuperar información. Existen muchas bases de datos relacionales, las más difundidas son MySQL, Oracle, SQL Server y PostgresSQL. Cada una de ellas es compatible con el estándar SQL, aunque cada una de ellas tiene un juego de instrucciones propias. 12.1. Estructura de una BDD relacional. Dentro de una BDD relacional la información se estructura en tablas, es decir, filas y columnas. Cada columna representa un “campo” y cada fila un “registro”. nombre José María David Olga Fernando Marta apellidos Gutiérrez García Martínez Fernández Ruiz García puntuacion 57 88 78 78 78 25 sexo H M H M H M fecha_de_nacimiento 1977-04-03 1980-12-09 1976-11-02 1977-12-03 1979-01-04 1981-12-03 Comunidad_id 2 3 8 1 2 4 “Sexo”, En esta tabla “Alumnos” tenemos los campos “Nombre”, “Apellidos”, “Edad”, “comunidad_id” y los registros formados por los datos de los alumnos. 12.2. Los tipos de datos de MySQL A la hora de crear las tablas es necesario indicar el tipo de datos que van a contener. Estos son los tipos más importantes que se pueden definir para MySQL. Los corchetes indican que el argumento es opcional. • TINYINT[(M)] [UNSIGNED] [ZEROFILL] Número entero. El rango con signo es de -128 a 127. El rango sin signo es de 0 a 255. • SMALLINT[(M)] [UNSIGNED] [ZEROFILL] Número entero. El rango con signo es de -32768 a 32767. El rango sin signo es de 0 a 65535. • MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL] Número entero. El rango con signo es de -8388608 a 8388607. El rango sin signo es de 0 a 8388607. • INT[(M)] [UNSIGNED] [ZEROFILL] Número entero. El rango con signo es de -2147483648 a 2147483647. El rango sin signo es de 0 a 4294967295. 20 Su formato es “AAAA-MM-DD HH:MM:SS”.2250738585072014E-308 a 1. Las búsquedas efectuadas en un campo BLOB son sensibles a mayúsculas mientras que las búsquedas en un campo TEXT no lo son. • MEDIUMBLOB y MEDIUMTEXT Análogo a los campos BLOB y TEXT. El rango sin signo es de 0 a 18446744073709551615. • CHAR [(M)] Campo alfanumérico. y 1. Longitud máxima 4294967295 caracteres.7976931348623157E+308 a 2. Longitud máxima 16777215 caracteres. • LONGBLOB y LONGTEXT Análogo a los campos BLOB y TEXT. El rango válido es de “1000-01-01 00:00:00” a “9999-12-31 23:59:59”. • VARCHAR [(M)] Campo alfanumérico de longitud variable. Los campos “nombre” y “apellidos” deben ser “VARCHAR(100)”. 0.402823466E+38.7976931348623157E+308 • DATE Un campo de fecha con formato “AAAA-MM-DD”. El campo BLOB suele utilizarse para almacenar archivos. Si se especifica “UNSIGNED” los valores negativos son descartados.175494351E-38.402823466E+38 a 1.175494351E-38 a 3. y 2. pero con sus valores comprendidos desde 1.2250738585072014E-308. . La longitud máxima es de 65535. La longitud está fijada por “M”. M es el número de caracteres que se imprimirán cuando se haga la consulta y D el número de decimales que se representarán. El rango con signo es de -9223372036854775808 a 9223372036854775807.D)] [UNSIGNED] [ZEROFILL] Número de punto flotante (decimal).D)] [UNSIGNED] [ZEROFILL] Igual que “FLOAT”. “puntuación” “comunidad_id” deben ser “TINYINT UNSIGNED”. Utiliza MySQLFront para crear una tabla “alumnos” capaz de albergar los datos de nuestra tabla de ejemplo. Los valores válidos comprenden de -3. • DOUBLE[(M. • FLOAT[(M.html Ejercicio 16. 0. La longitud máxima está determinada por “M”.mysql. El límite es 255 caracteres.com/doc/en/Column_types. “sexo” debe ser “CHAR(1)” y “fecha de nacimiento” del tipo “DATE”. Más información sobre los tipos de datos de MySQL: http://www. El rango válido es de “1000-01-01'a ' 999912-31” • DATETIME Campo de fecha y hora.PHP+SQL Guía del curso • BIGINT[(M)] [UNSIGNED] [ZEROFILL] Número entero. • BLOB y TEXT Campos alfanuméricos largos. 21 . valorN) INSERT INTO alumnos (nombre.. Inserta los datos de nuestra tabla de ejemplo en tu tabla “alumnos”. ‘M’.3. Crea otra tabla con dos campos. INSERT INTO alumnos VALUES (‘María’. from tabla1 [AS talias1]. mysql> select 7+3 -> 10 Para extraer datos de tablas debemos escribir la expresión con la siguiente sintaxis: SELECT talias1. 88.mysql. combinando u ordenando entre otras tareas.2.columna2.PHP+SQL Guía del curso 12. Nótese que el campo numérico no necesita comillas.. ‘1980-12-9’) Inserta un registro con todos los campos.. Inserta datos en una tabla.columnaN)] VALUES (valor1. Consultas. ‘Gutiérrez’) Inserta un registro con “nombre” y “apellidos” el resto de campos queda con su valor por defecto. Su sintaxis es: SELECT expresión [FROM referencia_a_tablas] [[LEFT] [RIGHT] [INNER] JOIN referencia_a_tablas ON expresión_where] [WHERE expresión_where] [ORDER BY columna] [ASC o DESC] [LIMIT [límite.1. Las más sencillas son de carácter aritmético o lógico. La sintaxis es: INSERT [INTO] tabla [(columna1.] registros]] La expresión puede ser de distintos tipos. un campo numérico autoincrementable llamado “id” y otro de texto llamado “nombre”. ‘García’.valor2. Referencia: http://www. Ejercicio 17.campo1 [AS alias].3.….. 12. talias2. Si utilizamos “AS” cambia el nombre de las columnas devueltas. Inserta los nombres de algunas comunidades autónomas.html 12.campo2 [AS alias2]. 22 .. Select Extrae datos de una o varias tablas.…. apellidos) VALUES (‘José.. tabla2 [AS talias1]. nombre FROM alumnos Apellidos Gutiérrez García Martínez Fernández Ruiz García Nombre José María David Olga Fernando Marta En este caso no hace especificar “talias” porque sólo hay referencia a una tabla. si es necesario.3. Insert. Veamos algunos ejemplos: SELECT apellidos.com/doc/en/INSERT. WHERE nos permite establecer condiciones de tipo aritmético o lógico en la consulta: SELECT nombre. comunidades m Esta consulta es equivalente a la anterior. será alfabético en un campo de texto. el máximo y el mínimo de la columna seleccionada. Podemos utilizar ORDER BY para ordenar nuestros registros. nombre AS nom FROM alumnos ap Gutiérrez García Martínez Fernández Ruiz García nom José María David Olga Fernando Marta Mediante CONCAT podemos pedir que se nos devuelvan los datos en una sola columna. nombre DESC La última consulta ordena los resultados por puntos de manera ascendente.PHP+SQL Guía del curso SELECT apellidos AS ap.apellidos. Es posible usar alias para los nombres de las tablas: SELECT a.’.nombre. Podemos hacer referencia a varias tablas para combinar los datos. SELECT SELECT SELECT SELECT * * * * FROM FROM FROM FROM alumnos alumnos alumnos alumnos ORDER ORDER ORDER ORDER BY BY BY BY nombre nombre DESC fecha_de_nacimiento puntuacion ASC. SELECT SUM(puntuacion) FROM alumnos COUNT nos dirá el número de registros seleccionados. El tipo de ordenamiento se elige automáticamente dependiendo del tipo de columna.apellidos. Si dos alumnos tienen la misma puntuación los ordena de manera alfabética descendente.nombre’) AS nombre_completo FROM alumnos Las funciones SUM.apellidos. SELECT COUNT(nombre) FROM alumnos SELECT COUNT(*) FROM alumnos LIMIT nos permitirá controlar el número de registros devueltos (limit es propio de MySQL). ‘Nombre: ‘. AVG.2 Devuelve dos registros empezando por el cuarto (el primer registro es el 0). el valor medio. MAX y MIN devuelven la suma. respectivamente. etc. meses Extrae una tabla combinada. apellidos. SELECT * FROM alumnos LIMIT 2 Devuelve los dos primeros registros SELECT * FROM alumnos LIMIT 3. numérico en un campo numérico. SELECT alumnos. MySQL ordena de manera ascendente por defecto. m. alumnos. SELECT CONCAT(‘Apellidos: ‘. meses.nombre FROM alumnos a. a.nombre. puntuacion FROM alumnos WHERE puntuacion=88 23 . Con ASC y DESC forzamos el ordenamiento ascendente o descendente.nombre FROM alumnos. UPDATE alumnos SET comunidad_id=1. Si no se especifica WHERE se actualizan todos los registros de la tabla.comunidad_id. a.apellidos.html 12. a. SELECT a.id. apellidos. Veamos un ejemplo. puntuacion=80 WHERE fecha_de_nacimiento>’1978-1-1’ Asigna los valores “comunidad_id” y “puntuación” indicados a todos los alumnos nacidos después del 1-1-78.mysql. [campo2=valor2…] [WHERE sentencia_where] La sentencia WHERE es la misma descrita para SELECT. Vamos a ver como funciona.com/doc/en/Functions. c.3. c. 24 .PHP+SQL Guía del curso SELECT nombre. c. “ON” admite las mismas condiciónes que “WHERE”. SELECT a. puntuacion FROM alumnos WHERE puntuacion>70 SELECT nombre.nombre.nombre.id Referencia: http://www.nombre FROM alumnos a INNER JOIN comunidades c ON a.3. UPDATE también admite “ORDER BY” y “LIMIT”. puntuacion FROM alumnos WHERE puntuacion>70 AND ( sexo!=’H’ OR fecha_de_nacimiento<’1977-1-1’) “!=” y “<>” son equivalentes y representan “distinto de”.comunidad_id=c. Se utiliza con LIKE.id “Alumnos” es la tabla de la izquierda.id.id SELECT a. a. a. a.comunidad_id=c. apellidos.comunidad_id.id. apellidos. c. “LIMIT”. Update Con esta instrucción podemos modficar el contenido de los registros.nombre FROM alumnos a. etc.comunidad_id=c. Su sintaxis es: UPDATE tabla SET campo1=valor1.apellidos. “INNER JOIN” presenta únicamente los registros cruzados coincidentes. “ORDER BY”.com/doc/en/SELECT. “%” Es un caracter comodín que representa cualquier cadena.comunidad_id.apellidos. Este tipo de consultas también admite “WHERE”. c. a. Si en la tabla “comunidades” hubiera varios “id” idénticos “select” multiplicaría los registros coincidentes en “alumnos” el número de veces que fuera necesario. puntuacion FROM alumnos WHERE puntuacion>70 AND sexo=’M’ SELECT nombre.nombre. comunidades c WHERE a. SELECT apellidos FROM alumnos WHERE apellidos LIKE ‘%ez’ El elemento JOIN nos permitirá ajustar la manera en la que se combinan las tablas.html Más información sobre funciones propias de MySQL http://www. En nuestro caso estas dos consultas son equivalentes. Esta consulta presenta completa la tabla “alumnos” asociando a cada registro de la misma otro registro de la tabla “comunidades” que cumpla la condición expresada en “on”. “RIGHT JOIN” es análogo a “LEFT JOIN” intercambiando los papeles de la tabla izquierda y derecha. c.mysql.nombre FROM alumnos a LEFT JOIN comunidades c ON a. 4.PHP+SQL Guía del curso 12. PHP+SQL Veremos en este capítulo como utilizar PHP para trabajar con los registros de bases de datos relacionales. Casi en cualquier sitio construido con PHP encontraremos que trabaja contra una base de datos relacional. nombre de usuario y contraseña. mysql_pconnect mysql_pconnect([servidor [. Hay que especificar el servidor. $conn = mysql_pconnect(‘127. La posibilidad de utilizar PHP como interfaz con el usuario de una base de datos relacional dota a los sitios web de una gran interactividad. En caso de fallo en la conexión la función devuelve FALSE. Delete DELETE FROM tabla [WHERE expresión_where] Elimina todos los registros que encajen en la “expresión_where”.3.php 13. DELETE admite “ORDER BY” y “LIMIT”. 13. etc.0. Si consultamos la referencia de PHP veremos que posee librerías para trabajar con gran número de bases de datos. mSQL.’contraseña’). En la referencia encontraremos las funciones que necesitamos: http://www. entre las que se encuentran Oracle.2. $conn = mysql_pconnect(‘/var/run/mysqld/mysqld. SQLServer. PostgreSQL.net/manual/en/ref. <? $conn = mysql_pconnect(‘localhost’.sock’.’alu0’.1.1. Funciones 13. MySQL.’contraseña’).’contraseña’).login [. En caso de éxito en la conexión la función devuelve un “RECURSO”.1’.php. Si la base de datos es local la comunicación entre PHP y MySQL se realiza mediante un socket UNIX.’alu0’.1. Esto lo podemos encontrar en casi todas las funciones. un tipo especial de datos. identificador_de_recurso]) 25 . Nosotros trabajaremos contra MySQL. Si no se especifica WHERE se eliminan todos los registros de la tabla.1. 13. Es válido especificar la ruta hasta el socket UNIX en “servidor”. Siempre que tengamos que hacer referencia a esta conexión deberemos utilizar la referencia al recurso almacenado en la variable “$conn”. ?> Las tres funciones anteriores son equivalentes.’alu0’. mysql_select_db mysql_select_db (base_de_datos [.0.password ]]]) Abre una conexión persistente a la base de datos.mysql. Los recursos de PHP no son punteros. en caso contrario se realiza sobre IP. mysql_query mysql_query (consulta [. Cuando tengamos que hacer consultas con variables adquiridas por POST o GET debemos aplicar primero esta función antes de integrar las variables en la cadena de consulta. Vamos a ver un ejemplo: 26 . Si no se especifica el identificador de recurso se utiliza el último abierto. mysql_fetch_row mysql_fetch_row (recurso_consulta) Recupera un registro de la base de datos y lo devuelve en un array. <? mysql_select_db (‘alu’. el lugar más vulnerable de un site.PHP+SQL Guía del curso Establece el nombre de la base de datos con la que vamos a trabajar.2. Evita que un usuario malicioso inserte caracteres de escape dentro de una variable alterando así el comportamiento de la consulta. $conn).5. Es conveniente crear una o varias funciones que se encarguen del manejo de la base de datos. 13.1. $conn). mysql_query devuelve un vínculo a un recurso “consulta” o FALSE. de esta manera el código quedará más limpio y cualquier error será subsanado rápidamente. <? $array = mysql_fetch_row ( $recurso_consulta ). con frecuencia. La función devolverá FALSE cuando se hayan terminado los registros. Trabajando con la base de datos. ?> 13.4. identificador_de_recurso]) Envía una consulta a la base de datos.3. $nombre = mysql_escape_string ($nombre). así que hay que ser cuidadosos a la hora de construir estas funciones. mysql_escape_string mysql_escape_string (cadena) Esta función es fundamental para la seguridad. ?> 13.1. El punto en el que PHP consulta con la base de datos es. Las siguientes llamadas a mysql_fetch_row recuperarán los registros posteriores. ?> 13. Si no se especifica identificador de recurso se utiliza el devuelto por la última operación mysql_pconnect. <? $recurso_consulta = mysql_query (“select * from alumnos”.1. } return true. } /* Los caracteres especiales \n nos ayudarán a la hora de examinar el código fuente de la página generada. ‘alu0’). Crea una página donde los usuarios puedan insertar. return false. modificar y eliminar los registros de la tabla “alumnos”. */ function db_query($sql){ if ( ! $conn = mysql_pconnect(SERVER. } return $query. } // La variable “puntos” es introducida por el usuario. // NUNCA debemos olvidar usar esta función if ($query = db_query (“select * from alumnos where puntuacion>’$puntos’”)){ while ($row = mysql_fetch_row($query)){ print “<tr>”. /* Con esta función evitamos que puedan aparecer mensajes de error personalizados en modo de depuración desactivado. } if ( ! mysql_select_db(DB. ‘pass’). */ ?> Ejercicio 18 Desarrolla un iterfaz web para la base de datos. ‘alu0’). } /* Esta función realiza todos los pasos necesarios para efectuar la consulta. // Modo de depuración activado-desactivado (SERVER.PHP+SQL Guía del curso <? define define define define define (DEBUG. print “</font></br>”. USER. 27 . foreach ( $row as $out ) print “<td>$out</td>”. print $text. (DB. PHP posee funciones propias para controlar los mensajes de error. return false. } print “</table>\n”. (USER. (PASS. return false. ‘localhost’).$conn) ){ stderr(“Error al seleccionar la base de datos”). } if ( ! $query = mysql_query($sql. print “<table border=1>\n”.$conn) ){ stderr (“Error al efectuar la consulta: $sql”). PASS)){ stderr(“Error en la conexión”). así prevenimos que un posible atacante pueda recabar información sobre el site. */ function stderr($text){ if (DEBUG==1){ print “<br><font style=’color: red’>”. print “</tr>\n”. 1). $puntos=mysql_escape_string($puntos).