# Ejercicios - Bases de datos 2 - Comentarios

Esta página contiene comentarios ampliados con fragmentos de código PHP.

## Bases de datos 2-1 - Comprobaciones

- En cualquier consulta, compruebe que la consulta no ha dado error.

  En el ejemplo siguiente se comprueba el resultado de la consulta antes de seguir. La consulta podría dar error si el SGBD no está disponible, si la base de datos no ha sido creada todavía, etc. Si es así, poco se puede hacer, salvo informar al ususario del problema.

      $consulta = "SELECT COUNT(*) FROM $dbTabla";
      $result = $db->query($consulta);
      if (!$result) {
          print "<p>Error en la consulta.</p>\n";
      } else {
       ...

  Si se añade una consulta a una página que no la tenía, hay que conectarse a la base de datos al principio y cerrar la conexión al final.

      $db = conectaDb();
       ...
      $db = NULL;

- funciones.php
  - Defina una constante que contenga el máximo número de registros que puede contener la agenda.

        define('MAX_REG_TABLA', 20);  // Número máximo de registros en la tabla

- anyadir1.php
  - Compruebe que no se ha alcanzado ya el número máximo de registros.

    En el ejemplo siguiente la consulta devuelve un único registro con una única columna, que se obtiene con el método $result->fetchColumn().

        $consulta = "SELECT COUNT(*) FROM $dbTabla";
        $result = $db->query($consulta);
        if (!$result) {
            print "<p>Error en la consulta.</p>\n";
        } elseif ($result->fetchColumn()>=MAX_REG_TABLA) {
            print "<p>Se ha alcanzado el número máximo de registros que se pueden "
                 ."guardar.</p>\n<p>Por favor, borre algún registro antes.</p>\n";
        } else {
         ...

- anyadir2.php
  - Compruebe que el ususario no ha dejado todos los campos vacíos.

        if (($nombre=="") && ($apellidos=="")) {
            print "<p>Hay que rellenar al menos uno de los campos. "
                ."No se ha guardado el registro.</p>\n";
        } else {
         ...

  - Compruebe que no se ha alcanzado ya el número máximo de registros.

    Es conveniente hacer esta comprobación aunque se haya hecho ya en anyadir1.php, ya que otro usuario puede haber introducido registros mientras el primer usuario estaba rellenando el formulario de anyadir1.php.

  - Compruebe que el registro que quiere introducir el usuario no ha sido ya incluido en la agenda.

    Esta consulta se debe realizar con sentencias preparadas ya que incluye datos proporcionados por el usuario.

        $consulta = "SELECT COUNT(*) FROM $dbTabla
            WHERE nombre=:nombre
            AND apellidos=:apellidos";
        $result = $db->prepare($consulta);
        $result->execute(array(':nombre' => $nombre, ':apellidos' => $apellidos));
        if (!$result) {
            print "<p>Error en la consulta.</p>\n";
        } elseif ($result->fetchColumn()>0) {
            print "<p>El registro ya existe.</p>\n";
        } else {
         ...

- listar.php
  - Compruebe que hay registros que listar en la agenda.

    Esta comprobación es similar a la de comprobar que no se ha alcanzado el máximo de registros.

        $consulta = "SELECT COUNT(*) FROM $dbTabla";
        $result = $db->query($consulta);
        if (!$result) {
            print "<p>Error en la consulta.</p>\n";
        } elseif ($result->fetchColumn()==0) {
            print "<p>No se ha creado todavía ningún registro.</p>\n";
        } else {
         ...

- borrar1.php
  - Compruebe que hay registros que borrar en la agenda.

    Esta comprobación es la misma que la de listar.php

- borrar2.php
  - Compruebe que se ha marcado algún registro para borrar.

    Como $id es una matriz, esta comprobación se puede hacer contando los elementos recibidos utilizando la funcion count().

        $id = recogeMatriz('id');

        if (count($id)==0) {
            print "<p>No se ha seleccionado ningún registro.</p>\n";
        } else {
         ...

- buscar1.php
  - Compruebe que hay registros que buscar en la agenda.

    Esta comprobación es la misma que la de listar.php

- buscar2.php
  - Compruebe que se han encontrado registros.

    Esta comprobación es similar a la de comprobar que no se ha alcanzado el máximo de registros, pero utilizando sentencias preparadas:

        $consulta = "SELECT COUNT(*) FROM $dbTabla
            WHERE nombre LIKE :nombre
            AND apellidos LIKE :apellidos";
        $result = $db->prepare($consulta);
        $result->execute(array(':nombre' => "%$nombre%", ':apellidos' => "%$apellidos%"));
        if (!$result) {
            print "<p>Error en la consulta.</p>\n";
        } elseif ($result->fetchColumn()==0) {
            print "<p>No se han encontrado registros.</p>\n";
        } else {
         ...

- modificar1.php
  - Compruebe que hay registros que modificar en la agenda.

    Esta comprobación es la misma que la de listar.php

- modificar2.php
  - Compruebe que se ha marcado algún registro para modificar.

    Esta comprobación es similar a la de comprobar que se ha marcado algún registro para borrar, pero en este caso no se trata de una matriz

        $id = recoge('id');

        if ($id=='') {
            print "<p>No se ha seleccionado ningún registro.</p>\n";
        } else {
         ...

  - Compruebe que se ha encontrado el registro seleccionado para modificar.

    Esta comprobación es similar a la de comprobar que se han encontrado registros de buscar2.php.

        $consulta = "SELECT COUNT(*) FROM $dbTabla
            WHERE id=:id";
        $result = $db->prepare($consulta);
        $result->execute(array(':id' => $id));
        if (!$result) {
            print "<p>Error en la consulta.</p>\n";
        } elseif ($result->fetchColumn()==0) {
            print "<p>Registro no encontrado.</p>\n";
        } else {
         ...

- modificar3.php
  - Compruebe que se ha recibido el id del registro a modificar

    Esta comprobación es la misma que la de modificar2.php.

  - Compruebe que el ususario no ha dejado todos los campos vacíos.

    Esta comprobación es la misma que la de modificar2.php.

  - Compruebe que el registro que quiere introducir el usuario no ha sido ya incluido en la agenda (es decir, que al modificar un registro lo hagamos coincidir con otro ya incluido en la agenda).

    Esta comprobación es similar a la de anyadir2.php, excepto que es necesario incluir el id en la consulta para el caso particular en que la modificación realizada haya sido cambiar alguna minúscula por minúscula o viceversa. El motivo es que sólo se incluyera el nombre y los apellidos MySQL diría que sí que hay un registro como el modificado (el registro a modificar).

        // La consulta cuenta los registros con un id diferente porque MySQL no distingue
        // mayúsculas de minúsculas y si en un registro sólo se cambian mayúsculas por
        // minúsculas MySQL diría que ya hay un registro como el que se quiere guardar.
        $consulta = "SELECT COUNT(*) FROM $dbTabla
            WHERE nombre=:nombre
            AND apellidos=:apellidos
            AND id<>:id";
        $result = $db->prepare($consulta);
        $result->execute(array(':nombre' => $nombre, ':apellidos' => $apellidos, ':id' => $id));
        if (!$result) {
            print "<p>Error en la consulta.</p>\n";
        } elseif ($result->fetchColumn()>0) {
            print "<p>Ya existe un registro con esos mismos valores. "
                 ."No se ha guardado la modificación.</p>\n";
        } else {
         ...

Volver al principio de la página

## Bases de datos 2-2 - Mejoras

- Listados ordenables (listar.php, borrar1.ph, buscar2.php, modificar1.ph)

  En cualquier listado en forma de tabla, permita ordenar los registros en un orden determinado (por cualquie campo, en orden ascendente o descendente).

  Para ello la consulta que selecciona todos los registros podría incluir un ORDER BY

      $consulta = "SELECT * FROM $dbTabla
                   ORDER BY $campo $orden";

  El campo y el orden deberían haber se recogido previamente (en el ejemplo siguiente, se les da valores predeterminados para que la primera vez que se listan los registros se haga por orden alfabético del apellido):

      $campo = recogeCampo('campo', 'apellidos');
      $orden = recogeOrden('orden', 'ASC');

  Las funciones recogeCampo() y recogeOrden() podrían ser las siguientes:

      $campos = array(
          'nombre',
          'apellidos');

      function recogeCampo($var, $var2)
      {
          global $campos;

          foreach($campos as $campo) {
              if (isset($_REQUEST[$var]) && $_REQUEST[$var]==$campo) {
                  return $campo;
              }
          }
          return $var2;
      }

      function recogeOrden($var, $var2)
      {
          if (isset($_REQUEST[$var]) && $_REQUEST[$var]=='ASC') {
              return 'ASC';
          } elseif (isset($_REQUEST[$var]) && $_REQUEST[$var]=='DESC') {
              return 'DESC';
          } else {
              return $var2;
          }
      }

  En la cabecera de la tabla se insertarían dos imágenes que enlazarían a la propia página enviando cada una un campo y orden diferente (en el ejemplo siguiente ordenaría por el campo nombre de forma ascedente o descendente).

      // En la dirección se escribe la entidad de carácter &amp; en vez del carácter &
      // para que el código HTML de la página sea válido

            <th><a href=\"$_SERVER[PHP_SELF]?campo=nombre&amp;orden=ASC\">
              <img src=\"abajo.png\" alt=\"A-Z\" title=\"A-Z\" /></a>
              Nombre
              <a href=\"$_SERVER[PHP_SELF]?campo=nombre&amp;orden=DESC\">
              <img src=\"arriba.png\" alt=\"Z-A\" title=\"Z-A\" /></a></th>

  Las imágenes (arriba.png y abajo.png) se pueden guardar de la página de ejemplo.

  En el caso de la búsqueda (buscar2.php), el enlace a la propia página debe enviar también los valores que introdujo el usuario en la búsqueda

      // En la dirección se escribe la entidad de carácter &amp; en vez del carácter &
      // para que el código HTML de la página sea válido

            <th><a href=\"$_SERVER[PHP_SELF]?$nombre=$nombre&amp;apellidos=$apellidos&amp;campo=nombre&amp;orden=ASC\">
              <img src=\"abajo.png\" alt=\"A-Z\" title=\"A-Z\" /></a>
              Nombre
              <a href=\"$_SERVER[PHP_SELF]?$nombre=$nombre&amp;apellidos=$apellidos&amp;campo=nombre&amp;orden=DESC\">
              <img src=\"arriba.png\" alt=\"Z-A\" title=\"Z-A\" /></a></th>

- Cursor en los formularios

  Para hacer más cómodo la utilización del programa, cuando una página contenga un formulario con campos de texto, el cursor debe aparecer en el primer campo de texto.

  Para ello la función cabecera puede tener un tercer argumento que escriba o no el código javascript correspondiente:

      // funciones.php
      define('CABECERA_CON_CURSOR',    TRUE);   // Para función cabecera()
      define('CABECERA_SIN_CURSOR',    FALSE);  // Para función cabecera()

      function cabecera($texto, $menu, $conCursor)
      {
       ...
          if ($conCursor) {
              print "<body onload=\"document.getElementById('cursor').focus()\">\n";
          } else {
              print "<body>\n";
          }
       ...

  En cada página en la que el cursor debe aparecer en un campo de texto se añadiría el atributo id correspondiente:

      // listar.php
              <td><input type=\"text\" name=\"nombre\" size=\"$tamNombre\" "
              ."maxlength=\"$tamNombre\" id=\"cursor\" /></td>

  En las páginas en la que no hay campos de texto, la función cabecera se debe llamar con el tercer argumento:

      // index.php
      cabecera('Inicio', MENU_PRINCIPAL, CABECERA_SIN_CURSOR);

  En las páginas en la que hay campos de texto, la función cabecera se debe llamar con el tercer argumento que corresponda, dependiendo de si se muestra o no el campo de texto:

      // anyadir1.php
      if (!$result) {
          cabecera('Añadir 1', MENU_VOLVER, CABECERA_SIN_CURSOR);
          print "<p>Error en la consulta.</p>\n";
      }
       ...
          cabecera('Añadir 1', MENU_VOLVER, CABECERA_CON_CURSOR);
          print "<form action=\"anyadir2.php\" method=\"".FORM_METHOD."\">
       ...

Volver al principio de la página

## Bases de datos 2-3 - Ampliaciones

No hay comentarios para este ejercicio.

Volver al principio de la página

Esta obra está bajo una licencia de Creative Commons Reconocimiento-CompartirIgual 3.0 España.