4 Añadir, modificar y eliminar datos

En este capítulo veremos cómo manipular datos contenidos en una base de datos, añadir, modificar o eliminar datos de tablas.

Insertar datos en una tabla

Evidentemente, la forma más simple de introducir datos en una tabla es usar una sentencia INSERT:

   mysql_query(myData, "INSERT INTO nombres (nombre) VALUES "
      "('Carlos'), "
      "('Felipe'), "
      "('Irene')");

Pero esto no es muy práctico, ya que generalmente tendremos que introducir datos suministrados por el usuario de la aplicación, y eso significa que debemos leer valores de atributos y crear consultas con valores variables.

En una consulta INSERT necesitaremos, generalmente, dos listas de valores. La primera es una lista de atributos, y la segunda una lista de valores para esos atributos. En el ejemplo usamos una lista de listas de valores de atributos, pero podemos simplificar el proceso haciendo una consulta para cada inserción en la tabla.

En nuestra base de datos "agenda", la tabla de nombres tiene dos atributos, pero el primero de ellos es un campo AUTO_INCREMENT, por lo que no será necesario especificar un valor cuando se inserten datos, ese valor se calcula de forma automática. Por lo tanto, la lista de atributos contiene un único valor: 'nombre'.

Veamos un ejemplo:

   // Insertar datos:
   cout << "introducir datos" << endl;
   char nombre[41];
   char *consulta;
   char resp;
   char patronnombre[] = "INSERT INTO nombres (nombre) VALUES(\'%s\')";
   do \{
      // Leer contacto:
      cout << "Nombre de contacto: " << flush;
      cin.getline(nombre, 41);
      consulta = new char[strlen(patronnombre)+strlen(nombre)-1];
      sprintf(consulta, patronnombre, nombre);
      mysql_query(myData, consulta);
      delete[] consulta;
      cout << "Otro contacto?: " << flush;
      cin >> resp;
      cin.ignore();
   } while (toupper(resp) == 'S');

Obtener el último valor autoincrementado insertado

Frecuentemente, como sucede en nuestra base de datos de ejemplo, tenemos que insertar datos en una tabla interrelacionada con otra. Para hacerlo necesitamos el valor del atributo referenciado. En nuestro ejemplo necesitamos conocer el último valor de 'id' generado para insertar los registros de teléfonos usando el mismo valor.

Para conseguir ese valor hay dos posibilidades. Una consiste en hacer una consulta para obtener el valor de la función LAST_INSERT_ID(). La otra, que nos resultará mucho más práctica, consiste en usar la función del API mysql_insert_id, que hace lo mismo, pero nos evita procesar un conjunto de resultados:

   // Insertar datos:
   cout << "introducir datos" << endl;
   char nombre[41];
   char tipo[21];
   char numero[15];
   char *consulta;
   char resp;
   my_ulonglong id;
   char patronnombres[] = "INSERT INTO nombres (nombre) VALUES(\'%s\')";
   char patrontelefonos[] = "INSERT INTO telefonos (id, tipo, numero) "
      "VALUES(\'%11d\', \'%s\', \'%s\')";
   do \{
      // Leer contacto:
      cout << "Nombre de contacto: " << flush;
      cin.getline(nombre, 41);
      consulta = new char[strlen(patronnombres)+strlen(nombre)-1];
      sprintf(consulta, patronnombres, nombre);
      mysql_query(myData, consulta);
      delete[] consulta;
      id = mysql_insert_id(myData);
      // Leer teléfonos:
      do \{
         cout << "Tipo de telefono: " << flush;
         cin.getline(tipo, 21);
         cout << "Numero de telefono: " << flush;
         cin.getline(numero, 15);
         consulta = new char[strlen(patrontelefonos)+11+strlen(tipo)+
            strlen(numero)-7];
         sprintf(consulta, patrontelefonos, static_cast<int>(id),
            tipo, numero);
         mysql_query(myData, consulta);
         delete[] consulta;
         cout << "Otro telefono?: " << flush;
         cin >> resp;
         cin.ignore();
      } while (toupper(resp) == 'S');
      cout << "Otro contacto?: " << flush;
      cin >> resp;
      cin.ignore();
   } while (toupper(resp) == 'S');

Eliminar datos de una tabla

Eliminar filas de una tabla es igualmente simple. Nos limitaremos a hacer una consulta DELETE con una cláusula WHERE de modo que sólo eliminemos las filas que queramos.

En nuestro ejemplo "agenda", las filas de teléfonos están relacionadas mediante una clave foránea a las filas de nombres, de modo que si se elimina una fila de nombres, automáticamente se eliminan todas las filas de teléfonos con el mismo valor de 'id'. Esto nos facilita la tarea de eliminar contactos completamente:

   // Eliminar un contacto:
   char patrondelete[] = "DELETE FROM nombres WHERE nombre = \"%s\"";
   cout << "Nombre a eliminar de agenda: " << flush;
   cin.getline(nombre, 41);
   consulta = new char[strlen(patrondelete)+strlen(nombre)-1];
   sprintf(consulta, patrondelete, nombre);
   mysql_query(myData, consulta);
   delete[] consulta;

Puede ser interesante conocer el número de filas afectadas por la sentencia DELETE. Se puede obtener una información análoga a la presentada en el cliente MySQL usando la función del API mysql_affected_rows:

mysql> DELETE FROM nombres WHERE nombre="Pepito";
Query OK, 1 row affected (0.01 sec)

Por ejemplo:

   cout << "Filas eliminadas: " << (int)mysql_affected_rows(myData) << endl;

Actualizar filas de una tabla

El proceso para modificar filas se explica con detalle en el capítulo 8 del curso de MySQL. Para hacerlo desde un programa C/C++ bastará con hacer las consultas UPDATE o REPLACE adecuadas.