viernes, 29 de mayo de 2009

Lista definitiva de traslados de Secundaria publicada

Como podéis ver en los siguientes enlaces se ha publicado la resolución definitiva del concurso de traslados de Educación Secundaria de la Xunta de Galicia. Por lo que respecta a Informática no hay ninguna variación desde la provisional con lo que el año que viene veremos a David por aquí de nuevo pero con su plaza definitiva.

Enlaces:
Página del concurso : https://www.edu.xunta.es/portal/contenido?comando=ContenidoDinamicoComando&accion=verRecurso&rID=fc8b37e0-0ab4f107-0782917a-650086f0&trID=64fd0927-c0a8fd03-006e7a5b-7dc3b488&lID=gl&pwID=e4763dcf-0a0a2825-006c0962-b0b5ef8f

Listado alfabético por disciplinas: http://www.edu.xunta.es/ftpserver/portal/DXP/secundaria/alfabetico_disciplinas_def.pdf

miércoles, 27 de mayo de 2009

Manual de PHP 81.MySQL: Proteger PHPMyAdmin

Borrado de usuarios MySQL
Hasta el momento no hemos modificado ni los usuarios de MySQL ni la configuración de PHPMyAdmin.

Aún tenemos los usuarios por defecto (root sin contraseña) y PHPMyAdmin sigue dándonos el mensaje de advertencia relativo al fallo de seguridad de la configuración.

El primer paso para corregir esa vulnerabilidad será borrar los usuarios dejando sólo el usuario pepe que es el que hemos creado al instalar MySQL.

Para ello, con el servidor MySQL activo, abriremos PhpMyAdmin editaremos la tabla user correspondiente a la base de datos mysql y borraremos los usuarios, dejando únicamente al usuario pepe.





Una vez realizados estos cambios, deberíamos cerrar el servidor MySQL y reiniciarlo con la nueva configuración. A partir de aquí, cuando tratamos de acceder de nuevo a PHPMyAdmin nos aparecerá un mensaje de error tal como el que vemos en la imagen.




PHPMyAdmin nos dará este mensaje de error porque su configuración por defecto utiliza el usuario root que ya no existe. ¡Acabamos de borrarlo!

Modificación de la configuración de PHPMyAdmin

Hemos de modificar el fichero config.inc.php que está en el sudirectorio libraires de MyAdmin. Un simple cambio, tal como el que ves en las imágenes será suficiente.



Bastará cambiar (en la línea 71 del fichero) la palabra config por http, guardar los cambios y, como siempre, reiniciar el servidor MySQL para que se active la protección de PHPMyAdmin.


Acceso a PHPmyAdmin

A partir del momento que hayamos hecho los cambios anteriores, cada vez que tratemos de acceder a http://localhost/MyAdmin/ nos aparecerá una ventana como la que vemos en la imagen. Será necesario introducir un nombre de usuario válido (pepe en nuestro caso).



Nos desaparecerá el mensaje de advertencia y ya podremos gestionar nuestras bases de datos de forma un poco más segura.




Manual de PHP 80.MySQL: Otras consultas

Definición de tablas

En este ejemplo de tablas vinculadas con integridad relacional vamos a proponer la situación siguiente.

Crearemos una primera tabla (alumnos) que va a contener datos personales de un grupo de personas.

Para evitar duplicar un mismo alumno y alumnos sin DNI, vamos a utilizar como índice primario (PRIMARY KEY) el campo DNI (que es único para cada persona).

La condición de que el campo DNI sea PRIMARY KEY nos obliga a definirlo con el flag NOT NULL, dado que esta es una condición necesaria para la definición de índices primarios.

Crearemos una segunda tabla (domicilios) con los domicilios de cada uno de los alumnos, identificándolos también por su DNI. Para evitar que un mismo alumno pueda tener dos domicilios asignamos a al campo DNI de esta tabla la condición de índice único (UNIQUE).

El índice UNIQUE podríamos haberlo creado también como PRIMARY KEY ya que la única diferencia de comportamiento entre ambos es el hecho que aquel admitiría valores NULOS pero, dado que debemos evitar domicilios sin alumnos, insertaremos el flag NOT NULL en este campo.

El hecho de utilizar dos tablas no tiene otro sentido que la ejemplificación ya que lo habitual sería que todos los datos estuvieran en una misma tabla.

Vincularemos ambas tablas de modo que no puedan crearse direcciones de alumnos inexistentes y les pondremos la opción de actualización y borrado en cascada. De esta forma las acciones en la tabla de alumno se reflejarían automáticamente en la tabla de domicilios.

La tercera de las tablas (evaluaciones) tiene como finalidad definir las distintas evaluaciones que puede realizarse a cada alumno. Tendrá dos campos. Uno descriptivo (el nombre de la evaluación) y otro identificativo (no nulo y único) que será tratado como PRIMARY KEY para evitar duplicidades y porque, además, va a ser utilizado como clave foránea en la tabla notas.

La tabla notas va a tener tres campos: DNI, nº de evaluación y calificación.

Estableceremos restricciones para evitar que:

* Podamos calificar a un alumno inexistente.
* Podamos calificar una evaluación no incluida entre las previstas.
* Podamos poner más a cada alumnos más de una calificación por evaluación.

Creando una índice primario formado por los campos DNI y evaluación evitaremos la última de las situaciones y añadiendo una vinculación con las tablas alumnos y evaluaciones estaremos en condiciones de evitar las dos primeras.

En este gráfico puedes ver un esquema de la definición de estas tablas.


Importación y exportación de datos
Es esta una opción interesante por la posibilidad que ofrece de intercambiar datos entre diferentes fuentes y aplicaciones.

Importación de ficheros
MySQL permite insertar en sus tablas los contenidos de ficheros de texto. Para ello utiliza la sentencia que tienes al final y que detallaremos a continuación.

LOAD DATA INFILE
Es un contenido obligatorio que defina la opción de insertar datos desde un fichero externo.

nombre del fichero
Se incluye inmediatamente después de la anterior, es obligatorio y debe contener (entre comillas) la ruta, el nombre y la extensión del fichero que contiene los datos a insertar.

[REPLACE|IGNORE]
Es opcional. Si se omite se producirá un mensaje de error si el fichero contiene valores iguales a los contenidos en los campos de la tabla que no admiten duplicados. Con la opción REPLACE sustituiría los valores existentes en la tabla y con la opción IGNORE

INTO TABLE nombre
Tiene carácter obligatorio y debe incluir como nombre el de la tabla a la que se pretende agregar los registros.

FIELDS
Tiene carácter OPCIONAL y permite incluir especificaciones sobre cuales son los caracteres delimitadores de campos y los que indican el final del campo. Si se omite FIELDS no podrán incluirse los ENCLOSED BY ni TERMINATED BY de campo.

ENCLOSED BY
Permite espeficar (encerrados entre comillas) los caracteres delimitadores de los campos. Estos caracteres deberán encontrarse en el fichero original al principio y al final de los contenidos de cada uno de los campos (por ejemplo, si el carácter fueran comillas los campos deberían aparecer así en el fichero a importar algo como esto: "32.45"). Si se omite esta especificación (o se omite FIELDS) se entenderá que los campos no tienen caracteres delimitadores.

Cuando se incluyen como delimitadores de campo las comillas (dobles o sencillas) es necesario utilizar una sintaxis como esta: '\"' ó '\'' de forma que no quepa la ambigüedad de si se trata de un carácter o de las comillas de cierre de una cadena previamente abierta.

TERMINATED BY
Se comporta de forma similar al anterior.
Permite qué caracteres son usados en el fichero original como separadores de campos (indicador de final de campo). Si se omite, se interpretará con tal el carácter tabulador (\t).

El uso de esta opción no requiere que se especifique previamente ENCLOSED BY pero si necesita que se haya incluido FIELDS. LINES
Si el fichero de datos contiene caracteres (distintos de los valores por defecto) para señalar el comienzo de un registro, el final del mismo o ambos, debe incluirse este parámetro y, después de él, las especificaciones de esos valores correspondientes a:

STARTING BY
Permite especificar una carácter como indicador de comienzo de un registro. Si se omite o se especifica como '' se interpretará que no hay ningún carácter que señale en comienzo de línea.

TERMINATED BY
Es el indicador del final de un registro. Si se omite será considerado como un salto de línea (\n).

Exportación de ficheros
Se comporta de forma similar al supuesto anterior. Utiliza la sintaxis siguiente:

SELECT * INTO OUTFILE
Inicia la consulta de los campos especificados después de SELECT (si se indica * realiza la consulta sobre todos los campos y por el orden en el que fue creada la tabla) y redirige la salida a un fichero.

nombre del fichero
Es la ruta, nombre y extensión del fichero en el que serán almacenados los resultados de la consulta.

FIELDS
ENCLOSED BY
TERMINATED BY
LINES
STARTING BY
TERMINATED BY
Igual que ocurría en el caso de importación de datos, estos parámetros son opcionales. Si no se especifican se incluirán los valores por defecto.

FROM nombre
Su inclusión tiene carácter obligatorio. El valor de nombre ha de ser el de la tabla sobre la que se realiza la consulta.

¡Cuidado!

Al importar ficheros habrá de utilizarse el mismo formato con el que fueron creados tanto FIELDS como LINES.

Consultas usando JOIN
La claúsula JOIN es opción aplicable a consultas en tablas que tiene diversas opciones de uso. Iremos viéndolas de una en una. Todas ellas han de ir incluidas como parámetros de una consulta. Por tanto han de ir precedidas de:

SELECT *
o de
SELECT nom_tab.nom_cam,..
donde nom_tab es un nombre de tabla y nom_camp es el nombre del campo de esa tabla que pretendemos visualizar para esa consulta. Esta sintaxis es idéntica a la ya comentada en páginas anteriores cuando tratábamos de consultas en varias tablas.

Ahora veremos las diferentes posibilidades de uso de JOIN

FROM tbl1 JOIN tbl2
Suele definirse como el producto cartesiano de los elementos de la primera tabla (tbl1) por lo de la segunda (tbl2).

Dicho de una forma más vulgar, esta consulta devuelve con resultado una lista de cada uno de los registros de los registros de la primera tabla asociados sucesivamente con todos los correspondientes a la segunda. Es decir, aparecerá una línea conteniendo el primer registro de la primera tabla seguido del primero de la segunda. A continuación ese mismo registro de la primera tabla acompañado del segundo de la segunda tabla, y así, sucesivamente hasta acabar los registros de esa segunda tabla. En ese momento, repite el proceso con el segundo registro de la primera tabla y, nuevamente, todos los de la segunda. Así, sucesivamente, hasta llegar al último registro de la primera tabla asociado con el último de la segunda.

En total, devolverá un número de líneas igual al resultado de multiplicar el número de registros de la primera tabla por los de la segunda.

FROM tbl2 JOIN tbl1
Si permutamos la posición de las tablas, tal como indicamos aquí, obtendremos el mismo resultado que en el caso anterior pero, como es lógico pensar, con una ordenación diferente de los resultados.

FROM tbl2 JOIN tbl1 ON cond
El parámetro ON permite añadir una condición (cond)a la consulta de unión. Su comportamiento es idéntico al de WHERE en las consultas ya estudiadas y permite el uso de las mismas procedimientos de establecimiento de condiciones que aquel operador.

FROM tbl1 LEFT JOIN tbl2 ON cond
Cuando se incluye la cláusula LEFT delante de JOIN el resultado de la consulta es el siguiente:
– Devolvería cada uno los registros de la tabla especificada a la izquierda de LEFT JOIN -sin considerar las restricciones que puedan haberse establecido en las claúsulas ON para los valores de esa tabla– asociándolos con aquellos de la otra tabla que cumplan las condiciones establecidas en la claúsula ON. Si ningún registro de la segunda tabla cumpliera la condición devolvería valores nulos.

FROM tbl1 RIGHT JOIN tbl2 ON cond
Se comporta de forma similar al anterior. Ahora los posibles valores nulos serán asignados a la tabla indicada a la izquierde de RIGHT JOIN y se visualizarían todos los registros de la tabla indicada a la derecha.

JOIN múltiples
Tal como puedes observar en el ejemplo, es perfectamente factible utilizar conjuntamente varios JOIN, LEFT JOIN y RIGHT JOIN. Las diferentes uniones irán ejecutándose de izquierda a derecha (según el orden en el que estén incluidos en la sentencia) y el resultado del primero será utilizado para la segunda unión y así sucesivamente.

En cualquier caso, es posible alterar ese orden de ejecución estableciendo otras prioridades mediante paréntesis.

UNION de consultas
MySQL permite juntar en una sola salida los resultados de varias consultas. La sintaxis es la siguiente:

(SELECT ...)
UNION ALL
(SELECT ...)
UNION ALL
(SELECT ...)

Cada uno de los SELECT ha de ir encerrado entre paréntesis.

Estructura de tablas y relaciones


Para desarrollar los ejemplos de este capítulo vamos a crear las tablas, cuyas estructuras e interrelaciones que puedes ver en el código fuente siguiente:

<?
$base="ejemplos";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
###############################################
# Creación de la tabla nombres con indice primario DNI
# tabla de nombres con índice primario en DNI
###############################################
$crear="CREATE TABLE IF NOT EXISTS alumnos (";
$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";
if(mysql_query ($crear ,$c)){
print "tabla <b>nombres</b> creada<BR>";
}else{
print "ha habido un error al crear la tabla <b>alumnos</b><BR>";
}
###############################################
# Creación de la tabla direcciones
# tabla de nombres con índice único en DNI
# para evitar dos direcciones al mismo alumno
# y clave foránea nombres(DNI)
# para evitar direcciones no asociadas a un alumno
# concreto. Se activa la opción de actualizar
# en cascada y de borrar en cascada
###############################################
$crear="CREATE TABLE IF NOT EXISTS domicilios (";
$crear.="DNI CHAR(8) NOT NULL, ";
$crear.="calle VARCHAR (20), ";
$crear.="poblacion VARCHAR (20), ";
$crear.="distrito VARCHAR(5), ";
$crear.=" UNIQUE identidad (DNI), ";
$crear.="FOREIGN KEY (DNI) REFERENCES alumnos(DNI) ";
$crear.="ON DELETE CASCADE ";
$crear.="ON UPDATE CASCADE ";
$crear.=") TYPE = INNODB";
if(mysql_query ($crear ,$c)){
print "tabla <b>domicilios</b> creada<br>";
}else{
print "ha habido un error al crear la tabla <b>domicilios</b><BR>";
}
###############################################
# Creación de la tabla nombres con indice primario EVALUACIONES
# tabla de nombres con índice primario en NUMERO
###############################################
$crear="CREATE TABLE IF NOT EXISTS evaluaciones (";
$crear.="NUMERO CHAR(1) NOT NULL, ";
$crear.="nombre_evaluacion VARCHAR (20) NOT NULL, ";
$crear.=" PRIMARY KEY(NUMERO)";
$crear.=")";
$crear.=" Type=InnoDB";
if(mysql_query ($crear ,$c)){
print "tabla <b>evaluaciones</b> creada<BR>";
}else{
print "ha habido un error al crear la tabla <b>evaluaciones</b><BR>";
}
###############################################
# Creación de la tabla notas
# indice UNICO para los campos DNI y evaluacion
# con ello se impide calificar dos veces al mismo
# alumno en la misma evaluacion
# claves foráneas (DOS)
# el DNI de nombres para evitar calificar a alumnos inexistentes
# el NUMERO de la tabla evaluaciones para evitar calificar
# DOS VECES en una evaluación a un alumno
###############################################
$crear="CREATE TABLE IF NOT EXISTS notas (";
$crear.="DNI CHAR(8) NOT NULL, ";
$crear.="evaluacion CHAR (1) NOT NULL, ";
$crear.="calificacion TINYINT (2), ";
/* observa que este indice primario está formado
por dos campos (DNI y evalucion) y que, como siempre
en el caso de PRIMARY KEY ambos son de tipo NOT NULL */
$crear.=" PRIMARY KEY vemaos(DNI,evaluacion), ";
/* Fijate en la secuencia siguiente:
1º.- Creamos el índice
2º.- Establecemos la clave foránea
3º.- Establecemo las condiciones ON DELETE
4º.- Establecemos las condiciones ON UPDTE
Es muy importe mantener esta secuencia para evitar
errores MySQL */
$crear.=" INDEX identico (DNI), ";
$crear.="FOREIGN KEY (DNI) REFERENCES alumnos(DNI) ";
$crear.="ON DELETE CASCADE ";
$crear.="ON UPDATE CASCADE,";
/* Esta tabla tiene dos claves foráneas asociadas a dos tablas
la anterior definida sobre alumnos como tabla principal
y esta que incluimos a continuación asociada con evaluaciones
Como ves repetimos la secuencia descrita anteriormente
Es importante establecer estas definiciones de una en una
(tal como ves en este ejemplo) y seguir la secuencia
comentada anteriormente */
$crear.=" INDEX evalua (evaluacion),";
$crear.="FOREIGN KEY (evaluacion) REFERENCES evaluaciones(NUMERO) ";
$crear.="ON DELETE CASCADE ";
$crear.="ON UPDATE CASCADE";
$crear.=") TYPE = INNODB";
if(mysql_query ($crear ,$c)){
print "tabla <b>notas</b> creada <BR>";
}else{
print "ha habido un error al crear la tabla <b>notas</b><BR>";
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}

mysql_close();
?>

Crear tablas ejemplo



Como puedes observar en la imagen del inicio, al definir la estructura de las tablas es muy importante prestar atención a que los campos vinculados sean del mismo tipo y dimensión.


Observa también que los campos de referencia de los vínculos que se establecen (en las tablas primarias) tienen que ser definidos como PRIMARY KEY y que, por tanto, han de establecerse como no nulos (NOT NULL).


Inserción de datos en tablas


MySQL permite importar ficheros externos utilizando la siguiente sintaxis:


LOAD DATA INFILE "nombre del fichero'
[REPLACE | IGNORE]

INTO TABLE nombre de la tabla

FIELDS
TERMINATED BY 'indicador de final de campo'

ENCLOSED BY 'caracteres delimitadores de campos'

LINES
STARTING BY 'caracteres indicadores de comienzo de registro'

TERMINATED BY 'caracteres indicadores del final de registro'



En este ejemplo pueder un caso práctico de inserción de datos en las tablas creadas anteriormente.


<?
$base="ejemplos";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
# hemos creado un fichero de texto (datos_alumnos.txt)
# que contiene datos de algunos alumnos. Los diferentes
# campos están entre comillas y separados unos de otros
# mediante un punto y coma.
# Cada uno de los registros comienza por un asterios
# y los registros están separados por un salto de línes (\r\n)
# Incluimos estás especificaciones en la sentencia de inserción
if(mysql_query("LOAD DATA INFILE
'c:/Apache/htdocs/cursoPHP/datos_alumnos.txt' REPLACE
INTO TABLE alumnos
FIELDS ENCLOSED BY '\"' TERMINATED BY ';'
LINES STARTING BY '*' TERMINATED BY '\r\n' ",$c)){
print "Datos de alumnos cargados<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}
# Para esta tabla usaremos el fichero datos_evaluaciones.txt
# Los diferentes
# campos están entre comillas y separados unos de otros
# mediante una coma.
# Cada uno de los registros comienza por un espacio
# y los registros están separados por un salto de línes (\r\n)
# Incluimos estás especificaciones en la sentencia de inserción
if(mysql_query("LOAD DATA INFILE
'c:/Apache/htdocs/cursoPHP/datos_evaluaciones.txt' REPLACE
INTO TABLE evaluaciones
FIELDS ENCLOSED BY '\'' TERMINATED BY ','
LINES STARTING BY ' ' TERMINATED BY '\r\n' ",$c)){
print "Datos de evaluaciones cargados<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}
/* En este caso no incluimos especificación alguna.
Bajo este suspuesto MySQL interpreta los valores por defecto
que son: los campos no van encerrados, las líneas no tienen
ningún carácter indicador de comienzo, los campos están separados
mediante tabulaciones (carácter de escape \t) y el final de línea
está señalado por un caracter de nueva línea (\n) */
if(mysql_query("LOAD DATA INFILE
'c:/Apache/htdocs/cursoPHP/datos_notas.txt' IGNORE
INTO TABLE notas",$c)){
print "Datos de notas cargados<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}
/* Se comporta como los casos anteriores con distincos caracteres
para los diferentes eventos, tal como puedes ver en el código */
if(mysql_query("LOAD DATA INFILE
'c:/Apache/htdocs/cursoPHP/datos_domicilios.txt' IGNORE
INTO TABLE domicilios
FIELDS ENCLOSED BY '|' TERMINATED BY '*'
LINES STARTING BY '#' TERMINATED BY '}' ",$c)){
print "Datos de domicilios cargados<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}mysql_close();
?>





Guardar datos en ficheros


MySQL permite los contenidos de sus tablas a ficheros de texto. Para ello utiliza la siguiente sintaxis:


SELECT * INTO OUTFILE "nombre del fichero'


FIELDS
TERMINATED BY 'indicador de final de campo'

ENCLOSED BY 'caracteres delimitadores de campos'

LINES
STARTING BY 'caracteres indicadores de comienzo de registro'

TERMINATED BY 'caracteres indicadores del final de registro'

FROM nombre de la tabla

<?
$base="ejemplos";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
if(mysql_query ("SELECT * INTO OUTFILE
'c:/Apache/htdocs/cursoPHP/alumnos.txt'
FIELDS ENCLOSED BY '\"' TERMINATED BY ';'
LINES STARTING BY '*' TERMINATED BY '\r\n'
FROM alumnos",$c)){
print "fichero alumnos.txt creado<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}
if(mysql_query ("SELECT * INTO OUTFILE
'c:/Apache/htdocs/cursoPHP/domicilios.txt'
FIELDS ENCLOSED BY '|' TERMINATED BY '*'
LINES STARTING BY '#' TERMINATED BY '}'
FROM domicilios",$c)){
print "fichero domicilios.txt creado<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}
if(mysql_query ("SELECT * INTO OUTFILE
'c:/Apache/htdocs/cursoPHP/notas.txt'
FROM notas",$c)){
print "fichero notas.txt creado<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}
if(mysql_query ("SELECT * INTO OUTFILE
'c:/Apache/htdocs/cursoPHP/evaluaciones.txt'
FIELDS ENCLOSED BY '\'' TERMINATED BY ','
LINES STARTING BY ' ' TERMINATED BY '\r\n'
FROM evaluaciones",$c)){
print "fichero evaluaciones.txt creado<br>";
}else{
echo mysql_error ($c)."<br>";
echo mysql_errno ($c);
}
mysql_close();
?>






Al exportar ficheros en entornos Windows, si se pretende que en el fichero de texto aparezca un salto de línea no basta con utilizar la opción por defecto de LINES TERMINATED BY '\n' sino LINES TERMINATED BY '\r\n' (salto de línea y retorno) que son los caracteres que necesita Windows para producir ese efecto.

Habrá de seguirse este mismo criterio cuando se trata de importar datos desde un fichero de texto.

Consultas de unión (JOIN)

<?
$base="ejemplos";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
# vamos a crear un array con las diferente consultas
# posteriormente lo leeremos y la ejecutaremos secuencialmente
/* Devuelve todos los campos de ambas tablas.
Cada registro de alumnos es asociado con todos los de domicilios*/
$query[]="SELECT * FROM alumnos JOIN domicilios";
/* Devuelve todos los campos de ambas tablas. Cada registro de domicilios
es asociado con todos los de alumnos */
$query[]="SELECT * FROM domicilios JOIN alumnos";
/* Devuelve todos los campos de los registros de ambas tablas
en los que coinciden los numeros del DNI*/
$query[]="SELECT * FROM alumnos JOIN domicilios
ON domicilios.DNI=alumnos.DNI";
/* Idéntica a la anterior. Solo se diferencia en que ahora
se visualizan antes los campos domicilios*/
$query[]="SELECT * FROM domicilios JOIN alumnos
ON domicilios.DNI=alumnos.DNI";
/* devuelve cada uno de los registro de la tabla alumnos. Si existe
un domicilio con igual DNI lo insertará. Si no existiera
insertará valores nulos en esos campos
$query[]="SELECT * FROM alumnos LEFT JOIN domicilios
ON domicilios.DNI=alumnos.DNI";
/* Se comporta de forma idéntica al anterior.
Ahora insertará todos los registros de domicilios
y los alumnos coincidentes o en su defecto campos nulos.*/
$query[]="SELECT * FROM domicilios LEFT JOIN alumnos
ON domicilios.DNI=alumnos.DNI";
/* Al utilizar RIGHT será todos los registros de la tabla de la derecha
(domicilios) los que aparezcan junto con las coincidencias o
junto a campos nulos. Aparecerán primero los campos de alumnos
y detrá los de domicilios*/
$query[]="SELECT * FROM alumnos RIGHT JOIN domicilios
ON (domicilios.DNI=alumnos.DNI AND alumnos.Nombre LIKE 'A%')";
/* Consulta de nombre, apellido y localidad de todos los alumnos
cuyo nombre empieza por A */
$query[]="SELECT alumnos.Nombre, alumnos.Apellido1,alumnos.Apellido2,
domicilios.poblacion FROM alumnos JOIN domicilios
ON (domicilios.DNI=alumnos.DNI
AND alumnos.Nombre LIKE 'A%')";
# una consulta resumen de nos permitirá visualizar una lista con nombre
# y apellidos de alumnos su dirección y localidad del domicilio
# el nombre de la evaluación y su calificación.
# Si no hay datos de población insertará ---- en vez del valor nulo
# y si no hay calificación en una evaluación aparecerá N.P.
# La consulta aparecerá agrupada por evaluaciones
/* iniciamos el select especificando los campos de las diferentes
tablas que prentendemos visualizar
$q="(SELECT alumnos.Nombre,alumnos.Apellido1,";
$q.=" alumnos.Apellido2,domicilios.calle,";
# al incluir IFNULL visualizaremos ---- en los campos cuyo resultado
# sea nulo
$q.=" IFNULL(domicilios.poblacion,'––––'),";
$q.=" evaluaciones.nombre_evaluacion,";
# con este IFNULL aparecerá N.P. en las evaluaciones no calificadas.
$q.=" IFNULL(notas.calificacion,'N.P.')";
# especificamos el primer JOIN con el que tendremos como resultado una lista
# de todos los alumnos con sus direcciones correspondientes
# por efecto de la clausula ON.
# Al poner LEFT se incluirían los alumnos que no tuvieran
# su dirección registrada en la tabla de direccione
$q.=" FROM (alumnos LEFT JOIN domicilios";
$q.=" ON alumnos.DNI=domicilios.DNI)";
# al unir por la izquierda con notas tendríamos todos los resultados
# del JOIN anterior asociados con con todas sus calificaciones
# por efecto de la claúsula ON
$q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI";
# al añadir esta nueva unión por la DERECHA con la tabla evaluaciones
# se asociaría cada uno de los resultados de las uniones anteriores
# con todos los campos de la tabla evaluaciones con lo que resultaría
# una lista de todos los alumnos con todas las calificaciones
# incluyendo un campo en blanco (sería sustituido por N.P:)
# en aquellas que no tuvieran calificación registrada
$q.=" RIGHT JOIN evaluaciones";
$q.=" ON evaluaciones.NUMERO=notas.evaluacion";
/* la clausula WHERE nos permite restringir los resultados a los valores
correspondientes únicamente a la evaluación número 1*/
$q.=" WHERE evaluaciones.NUMERO=1)";
# cerramos la consulta anterior con el paréntesis. Observa que lo
# hemos abierto delante del SELECT e insertamos UNION ALL
# para que el resultado de la consulta anterior aparezca
# seguido del correspondiente a la incluida después de UNION ALL
$q.=" UNION ALL";
#iniciamos (también con paréntesis) la segunda consulta
# que será identica a la anterior salvo el WHERE
# será modificado para extraer datos de la evaluación nº2
$q.="(SELECT alumnos.Nombre,alumnos.Apellido1,";
$q.=" alumnos.Apellido2,domicilios.calle,";
$q.=" IFNULL(domicilios.poblacion,'––––'),";
$q.=" evaluaciones.nombre_evaluacion,";
$q.=" IFNULL(notas.calificacion,'N.P.')";
$q.=" FROM (alumnos LEFT JOIN domicilios";
$q.=" ON alumnos.DNI=domicilios.DNI)";
$q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI";
$q.=" RIGHT JOIN evaluaciones";
$q.=" ON evaluaciones.NUMERO=notas.evaluacion";
$q.=" WHERE evaluaciones.NUMERO=2)";
# hemos cerrado el parentesis de la consulta anterior
# e incluimos un nuevo UNION ALL para consultar los datos
# correspondientes a la tercera evaluación
$q.=" UNION ALL";
$q.="(SELECT alumnos.Nombre,alumnos.Apellido1,";
$q.=" alumnos.Apellido2,domicilios.calle,";
$q.=" IFNULL(domicilios.poblacion,'––––'),";
$q.=" evaluaciones.nombre_evaluacion,";
$q.=" IFNULL(notas.calificacion,'N.P.')";
$q.=" FROM (alumnos LEFT JOIN domicilios";
$q.=" ON alumnos.DNI=domicilios.DNI)";
$q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI";
$q.=" RIGHT JOIN evaluaciones";
$q.=" ON evaluaciones.NUMERO=notas.evaluacion";
$q.=" WHERE evaluaciones.NUMERO=3)";
# incluimos la variable $q en el array de consultas
$query[]=$q;
# leemos el array y visualizamos el resultado
# cada consulta a traves de la llamada a la funcion visualiza
# a la que pasamos el resultado de la consulta
# y la cadena que contiene las sentencias de dicha consulta
foreach($query as $v){
visualiza(mysql_query($v,$c),$v);
}
function visualiza($resultado,$query){
PRINT "<BR><BR><i>Resultado de la sentencia:</i><br>";
print "<b><font color=#ff0000>";
print $query."</font></b><br><br>";
PRINT "<table align=center border=2>";
while ($registro = mysql_fetch_row($resultado)){
echo "<tr>";
foreach($registro as $valor){
echo "<td>",$valor,"</td>";
}
}
echo "</table><br>";
}




Fuente:

Página del ifstic: http://www.isftic.mepsyd.es/formacion/enred/

martes, 26 de mayo de 2009

Ciclo Medio "Técnico en sistemas microinformáticos y redes"

Distribución semanal para os centros que impartan as ensinanzas do ciclo formativo polo
réxime ordinario en sesións de 50 minutos.


Desde hace unos días se encuentra disponible en la página de la xunta el borrador del nuevo ciclo de grado medio "Técnico en sistemas microinformáticos e redes" perteneciente a la familia de informática y que sustituirá, a partir del año que viene, al actual de Explotación de Sistemas Informáticos.

Además de un cambio de nombre y de actualizar los contenidos para adaptarlos a las características del mercado y de los medios actuales, supone también un cambio en el número y denominación de los módulos que lo componen tal y como podréis comprobar en la imagen de cabecera y si pulsáis en el enlace Leer mas.

Distribución semanal para os centros que impartan oferta modular do ciclo formativo
polo réxime para as persoas adultas en sesións de 50 minutos.

Enlaces:


lunes, 25 de mayo de 2009

KON-BOOT: Acceso sin contraseña a sistemas Linux o Windows


Si necesitas acceder a un sistema con windows o Linux sin tener la contraseña y de modo no intrusivo, es decir sin dejar ningún rastro en los registros, sin lugar a dudas KON-BOOT es una buena solución.

Funciona cambiando los contenidos del kernel de Linux y de Windows durante el proceso de arranque en memoria, de tal modo que te permite entrar en Linux como usuario root y en Windows con cualquier perfil sin contraseña.

Actualmente funciona en los siguientes sistemas Windows:

  • Windows Server 2008 Standard SP2 (v.275)
  • Windows Vista Business SP0
  • Windows Vista Ultimate SP1
  • Windows Vista Ultimate SP0
  • Windows Server 2003 Enterprise
  • Windows XP
  • Windows XP SP1
  • Windows XP SP2
  • Windows XP SP3
  • Windows 7

y está probado con las siguientes versiones de Linux:

Gentoo 2.6.24-gentoo-r5
GRUB 0.97

  • Ubuntu 2.6.24.3-debug GRUB 0.97
  • Debian 2.6.18-6-6861 GRUB 0.97
  • Fedora 2.6.25.9-76.fc9.i6862 GRUB 0.97


Por lo que respecta a su funcionamiento es muy sencillo, tan sólo debemos descargarnos la iso del proyecto preparada ya para ser grabada en un disquete o un cd. Arrancamos nuestra imagen desde la imagen recién creada (en algunos equipos deberemos modificar el orden de arranque en la BIOS) y realizar los siguientes pasos:

1.- En Windows
Seleccionamos el perfil que queramos e introducimos cualquier password

2.- En Linux:
  1. Arrancamos con el CD o disquete de Kon-boot
  2. Cuando Linux ha cargado completamente vamos al modo consola
  3. Tecleamos 'kon-usr' como login, si funciona deberíamos estar en el sistema
  4. !Recuerda! restaurar el sistema cuando vayas a abandonarlo, para ello teclea 'kon-fix' como login de nuevo.

Ejemplo de salida de consola:

Ubuntu 8.04 torpeda tty1
torpeda login: kon-usr
# id
uid=0(root) gid=0(root)
# whoami
root

Problemas al loguearte???:

torpeda login: kon-usr
/bin/sh: Can't open kon-usr

FIX: type 'kon-fix' as login
* lo he probado con un Vista y funciona perfectamente,..... adiós a las contraseñas...y a las búsquedas de las palabras hack o hacking y windows/linux en google de un plumazo

Enlaces:

sábado, 23 de mayo de 2009

Reparar el arranque del disco duro: lilo, grub, windows,...

Imagen de la interfaz de Super Grub Disk en funcionamiento


Introducción

La situación es la siguiente: Un día se te ocurrió tener un computador con arranque dual. Entonces particionas el disco duro y te dispones a instalar alguna distribución (Ubuntu, OpenSuSE, Mandriva, etc) para luego instalar o reinstalar Microsoft Windows. Tras reiniciar el equipo te das cuenta de que Windows se inició automáticamente y de Linux, nada, desapareció. O en el peor de los casos simplemente da un error porque el MBR está corrupto y no puedes arrancarlo.

También es posible que tras algunos meses de uso de tu arranque dual y de ambos sistemas un buen día "amanezcas" con un mensaje avisándote de que el mbr está corrupto, lilo o grub no funcionan o ¨Windows no encuentra su sector de inicio.

Bueno estimado(a), ese es un error muy frecuente a la hora de hacer un “dual boot” en nuestra máquina.

En el primer caso, probablemente el error estuvo precisamente en la elección del orden de instalación de los sistemas operativos. Cuando quieran instalar dos o más sistemas operativos en un disco duro siempre dejen a Linux por último. Eso debe ser así porque Windows sobreescribre el MBR (Master Boot Record) en el momento de la instalación y borra cualquier gestor de arranque anteriormente instalado. Como a Microsoft Windows sólo le gusta compartir espacio con sus primogénitos, el orden de instalación ideal sería:

1. Windows 3.1
2. Windows 95
3. Windows 98
4. Windows NT
5. Windows ME
6. Windows 2000
7. Windows XP
8. Windows Vista
9. Linux, BSD, Solaris, etc

En el segundo caso, probablemente se deba a un error de escritura, corte de suministro o similar en algún momento de nuestro trabajo con el equipo.

Para cualquiera de los dos casos hay dos soluciones bastante sencillas, en la primera vamos a hacer uso de un software específico para recuperar los arranques de nuestros discos, en la segunda emplearemos un live-cd de arranque de cualquier distribución linux.

Ambas soluciones son "cortesía" de las páginas web que podéis ver, como siempre al final de la entrada. ( Esta vez toda mi tarea se ha limitado a un copy/paste y a modificar un enlace ).

----------------------------- PARA SEGUIR LEYENDO PULSA EN EL ENLACE LEER MAS



Reparar el arranque con Super Grub Disk (SGD)

Hay varias soluciones para reparar el arranque, pero hay una opción bastante completa y fácil de usar tal y cómo podéis ver en la imagen que encabeza esta entrada: Super Grub Disk (SGD)

Super Grub Disk es un Live CD que tiene una gran cantidad de funciones a la hora de arreglar el arranque roto, a las que se puede acceder de una manera fácil. Podemos reparar el arranque de Linux (Grub y Lilo), el de Windows y otros sistemas.

¿Cómo usarlo? Fácil: se debe descargar la imagen de SGD, grabarla (existen versiones para Floppy, USB y, por supuesto para grabar en un CD con cualquier programa de grabación ) y arrancar la computadora con el SGD en la unidad lectora. Con un par de teclas elegir la opciones deseadas y ¡Listo!, el arranque vuelve a andar.


Recuperar el Arranque con un Live-CD de Linux

Para solucionar el problema sólo necesitarás de un Live-CD Linux, como Knoppix por ejemplo (también sirve Ubuntu). Esta no es la forma más fácil de todas, pero sirve para cualquier distribución que hayas instalado en tu disco duro.

Cuando arranques el computador con el Live-CD deberás ubicarte en una terminal de comandos.

En el caso de Knoppix las particiones existentes en el disco duro son montadas como sólo-lectura, por lo tanto será necesario desmontar la partición que corresponde al sistema Linux que habías instalado en tu disco duro para luego volver a montarla como lectura-escritura.

Eso lo hacemos con:

umount /dev/hda2

En este ejemplo Linux se encuentra instalado en la 2º partición del disco maestro en el IDE primario, cámbienlo al que les corresponde si es necesario.

Luego crearemos una carpeta temporal para seguir trabajando desde ahí.

mkdir linuxdir

Y la montamos:

mount -w /dev/hda2 /linuxdir

Ahora ejecutaremos el comando chroot que nos permitirá configurar el directorio linuxdir (el que creamos recientemente) como si fuera el directorio raíz del sistema Linux instalado en el disco duro.
Entonces:

chroot linuxdir

Desde ahora todo lo que hagas en el terminal influirá en el sistema Linux que habías instalado en el disco duro. Es como si hubieras arrancado con él.

Ahora solo debes recuperar el gestor de arranque, sobreescribiendo el de Windows.

Si habías instalado GRUB con tu sistema Linux, entonces ejecutaremos:

grub-install /dev/hda (recuerden que en estos ejemplos el disco duro es el maestro del IDE 1, cámbienlo al que les corresponde si es necesario)

Si habías instalado LILO, entonces ejecutas:
lilo -v (el parámetro -v es opcional y sirve para mostrar en pantalla lo que el comando ha hecho)

Con esto ya deberías tener nuevamente un gestor de arranque en el MBR para ejecutar tu sistema Linux.

Ahora ejecutas:

exit (para salir del entorno chroot)
umount /linuxdir (para desmontar la partición de Linux anteriormente montada por ti)
reboot (para reiniciar la máquina, y recuerda quitar el Live-CD)


Enlaces:
Super Grub Disk (SGD): http://www.supergrubdisk.org/
ArchivoGeek: http://www.archivogeek.com/linux/general/como-recuperar-lilo-o-grub-en-el-mbr/
PcTux: http://www.pctux.com.ar/2007/09/reparar-el-arranque-con-super-grub-disk.html
La choza del tio tux: http://lachozadeltiotux.blogspot.com/2007/08/como-recuperar-tu-grub-despues-de.html

miércoles, 20 de mayo de 2009

Simulador electrónico de puertas lógicas


Simulador con el esquema de un biestable RS en funcionamiento -o eso espero que sea-

Como casi todos los que nos dedicamos a esto de la enseñanza, suelo hacer unos cuantos cursos al año para intentar actualizar conocimientos. Uno de los últimos que he hecho ha sido uno de electrónica. Buena parte de los ejercicios que debíamos realizar era simular algunos componentes con puertas lógicas; pero cuando pasabas de un equipo a otro te encontrabas con el problema de tener que instalar el software simulador (al estilo de Electronics Workbench), por supuesto si dispones de la licencia, o de software libre similar.

Ha sido finalizar el curso y encontrarme con esta página http://joshblog.net/projects/logic-gate-simulator/Logicly.html desde la que puedes emplear online y de modo gratuito un simulador de puertas lógicas muy sencillo, intuitivo y fácil de usar, basado en flash y que puede resultar muy útil para intentar explicar conceptos básicos.

lunes, 18 de mayo de 2009

Navegación anónima con tor




Existen múltiples maneras de realizar una navegación anónima por Internet, o lo que es lo mismo, que puedas visitar páginas web o emplear servicios de la Red sin que los equipos destinatarios de tu tráfico puedan obtener tu ip.

La mayoría de estos sistemas se basan en la utilización de proxys anónimos disponibles en Internet -de alguno de los cuales hablaré otro día- pero tienen el problema de suponer tan sólo un pequeño salto y no tener asegurada su disponibilidad ni ser factible su uso con otros servicios. Además el uso de algunos de ellos requiere el abono de alguna cantidad anual.

En aquellos lugares dónde es necesaria una mayor seguridad en la confidencialidad de nuestras comunicaciones podemos emplear la red tor que no es más que una red de equipos que se interconectan, de modo totalmente gratuito, reenviando el tráfico entre ellos de modo que sea imposible conocer su procedencia.

---------------------------------------------------- PULSA LEER MAS PARA SEGUIR LEYENDO

La mejor explicación es la de la página del proyecto:
"Tor es un proyecto software que le ayuda a defenderse contra el análisis de tráfico, una forma de vigilancia de la red que amenaza la libertad personal y la privacidad, la confidencialidad en los negocios y relaciones, y la seguridad del estado. Tor le protege transmitiendo sus comunicaciones a través de una red distribuída de repetidores llevados por voluntarios de todo el mundo: evita que alguien que observa su conexión a Internet aprenda qué sitios visita, y evita que los sitios que visita aprendan su posición física. Tor funciona con muchas de sus aplicaciones existentes, incluyendo navegadores web, clientes de mensajería instantánea, acceso remoto, y otras aplicaciones basadas en el protocolo TCP.

Cientos de miles de personas de todo el mundo usan Tor para una gran variedad de razones: periodistas y bloggers, trabajadores por los derechos humanos, fuerzas del orden, soldados, corporaciones, ciudadanos de regímenes represivos, y ciudadanos ordinarios."

Su instalación es muy sencilla y usando firefox dispondremos de un botón para habilitar/deshabilitar su funcionamiento. Si tenemos ancho de banda suficiente -más de 20kb/s- incluso podremos ceder parte de nuestro ancho de banda -de modo sencillo y fácilmente configurable- para que nuestro equipo también actúe como repetidor de la red con lo que ayudaremos a ocultar no sólo las conexiones de otros si no que también hará más difícil discernir si nuestro tráfico es originado por nosotros mismos o por otros usuarios.


Ventana de configuración de la conexión a la red
El único pero que le pondría es la ralentización de la conexión -bastante notable- que se produce habitualmente y dependiendo de los nodos a los que estés conectado en la red tor, pero si lo que buscas es el anonimato parece bastante razonable el sacrificar velocidad en aras de una mayor seguridad.


Enlaces
Página del proyecto: http://www.torproject.org/