Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Hartigan en 9 Agosto 2010, 01:03 am



Título: Error FOREIGN kEY sql server y c#
Publicado por: Hartigan en 9 Agosto 2010, 01:03 am
Bueno pues tengo un nuevo problema, me explico:

Como sabeis estoy haciendo una agenda electrónica. Para almacenar los contactos tengo una variable id que se autoincrementa en la bdd mi tabla es la siguiente:

Código
  1. CREATE TABLE contactos(
  2. id INT IDENTITY NOT NULL,
  3. titulo VARCHAR(50),
  4. nombre VARCHAR(50) NOT NULL,
  5. nombre2 VARCHAR(50),
  6. ape1 VARCHAR(50) NOT NULL,
  7. ape2 VARCHAR(50),
  8. apodo VARCHAR(50) NOT NULL,
  9. direccion VARCHAR(150),
  10. ciudad VARCHAR(20),
  11. provincia VARCHAR(20),
  12. cp VARCHAR(10),
  13. pais VARCHAR(20),
  14. telefono VARCHAR(20),
  15. movil VARCHAR(20),
  16. fax VARCHAR(20),
  17. web VARCHAR(50),
  18. twitter VARCHAR(50),
  19. facebook VARCHAR(50),
  20. direccion2 VARCHAR(150),
  21. ciudad2 VARCHAR(20),
  22. provincia2 VARCHAR(20),
  23. cp2 VARCHAR(10),
  24. pais2 VARCHAR(20),
  25. organizacion VARCHAR(50),
  26. puesto VARCHAR(50),
  27. departamento VARCHAR(50),
  28. oficina VARCHAR(50),
  29. telefono2 VARCHAR(20),
  30. fax2 VARCHAR(20),
  31. sexo VARCHAR(10),
  32. cumple VARCHAR(10),
  33. pareja VARCHAR(50),
  34. aniversario VARCHAR(10),
  35. comentario VARCHAR(1000),
  36. imagen Image,
  37. PRIMARY KEY (ID)
  38.  
  39. );


Tengo otra tabla para almacenar los emails de los contactos puesto que no se pueden introducir varios en la misma tabla o eso creo y he creado otra tabla de la siguiente manera:

Código
  1. CREATE TABLE email(
  2. id_contacto INT NOT NULL,
  3. email VARCHAR (100) NOT NULL,
  4. PRIMARY KEY (email, id contacto),
  5. FOREIGN KEY (id_contacto) REFERENCES contactos (id) ON DELETE CASCADE
  6. );

Lo que hago es introducir en una función primero los datos del contacto, sin los mails, y a continuación obtengo el id e introduzco los mail del contacto en el siguiente código:


Código
  1. public override bool Nuevo_Email(string correo)
  2.        {
  3.            bool exito = false;
  4.  
  5.            //Variable para el ide del contacto
  6.            int num_id = 0;
  7.  
  8.            String sentenciaSql = "SELECT COUNT (*) FROM contactos";
  9.  
  10.  
  11.            SqlConnection conexion = null;
  12.            DataTable data_table = null;
  13.            try
  14.            {
  15.                conexion = new SqlConnection(cadena_conexion);
  16.                SqlDataAdapter data_adapter = new SqlDataAdapter(sentenciaSql, conexion);
  17.                data_table = new DataTable();
  18.  
  19.                conexion.Open();
  20.                data_adapter.Fill(data_table);
  21.                conexion.Close();
  22.  
  23.                num_id = Convert.ToInt32(data_table.Rows[0][0].ToString());
  24.  
  25.                String query = "insert into email(id_contacto,email) values(" + num_id + ",'" + correo + "')";
  26.  
  27.                conexion = new SqlConnection(cadena_conexion);
  28.                conexion.Open();
  29.                SqlCommand cmd = new SqlCommand(query, conexion);
  30.                if ((1 != cmd.ExecuteNonQuery()))
  31.                {
  32.                    MessageBox.Show("Se ha producido un error al acceder a la fuente de datos", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  33.                    exito = false;
  34.                }
  35.                else
  36.                {
  37.                    exito = true;
  38.                }
  39.            }
  40.            catch (SqlException ex)
  41.            {
  42.               // MessageBox.Show("No se ha podido guardar en la base de datos", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
  43.                exito = false;
  44.            }
  45.            finally
  46.            {
  47.                if (conexion != null)
  48.                {
  49.                    if (conexion.State == ConnectionState.Open)
  50.                    {
  51.                        conexion.Close();
  52.  
  53.                    }
  54.                }
  55.            }
  56.            return (exito);
  57.  
  58.        }


Pero me da siempre el siguiente error:

Código:
ex = {"Instrucción INSERT en conflicto con la restricción FOREIGN KEY \"FK__email__id_contac__164452B1\". El conflicto ha aparecido en la base de datos \"agenda\", tabla \"dbo.contactos\", column 'id'.\r\nSe terminó la instrucción."}

Qué hago mal???

gracias de antemano.


Título: Re: Error FOREIGN kEY sql server y c#
Publicado por: Novlucker en 9 Agosto 2010, 04:15 am
Buenas ...

Yo en tu lugar no usaria sqldataadapter para una sentencia tan simple como consultar el número de registros de una tabla, sino que por el contrario utilizaría un procedimiento almacenado en la bbdd.

Por otra parte y siguiendo con lo mismo, tu das por hecho que el número de registros de la tabla es equivalente al id final de la misma, pero esto no necesariamente es así. Supongamos que tu ingresas 10 contactos y eliminas el último, el próximo id será el número 11, mientras que la tabla solo tendrá 10 registros para el count, con lo cual habrá un error en el insert. Te sugiero utilizar la función IDENT_CURRENT (http://msdn.microsoft.com/es-es/library/ms175098.aspx)

Saludos


Título: Re: Error FOREIGN kEY sql server y c#
Publicado por: [D4N93R] en 9 Agosto 2010, 04:53 am
Otras cosas:
  • Reutiliza la conexión.
  • Haces un Select * solo para traerte una columna de un registro?, mejor SELECT TOP 1 COLUMNA FROM TABLA
  • Según el diseño de tu BD cada persona puede tener muchos emails, no se si esto es lo que quieres hacer.

Con respecto a tu error, revisa que no haya data actual en esa tabla de emails.

Saludos


Título: Re: Error FOREIGN kEY sql server y c#
Publicado por: Hartigan en 9 Agosto 2010, 12:52 pm
Buenas ...

Yo en tu lugar no usaria sqldataadapter para una sentencia tan simple como consultar el número de registros de una tabla, sino que por el contrario utilizaría un procedimiento almacenado en la bbdd.

Por otra parte y siguiendo con lo mismo, tu das por hecho que el número de registros de la tabla es equivalente al id final de la misma, pero esto no necesariamente es así. Supongamos que tu ingresas 10 contactos y eliminas el último, el próximo id será el número 11, mientras que la tabla solo tendrá 10 registros para el count, con lo cual habrá un error en el insert. Te sugiero utilizar la función IDENT_CURRENT (http://msdn.microsoft.com/es-es/library/ms175098.aspx)

Saludos

Vale así lo haré, pero y como lo hago para leer un solo registro?? con un dataRow???

Otras cosas:
  • Reutiliza la conexión.
  • Haces un Select * solo para traerte una columna de un registro?, mejor SELECT TOP 1 COLUMNA FROM TABLA
  • Según el diseño de tu BD cada persona puede tener muchos emails, no se si esto es lo que quieres hacer.

Con respecto a tu error, revisa que no haya data actual en esa tabla de emails.

Saludos

Si no me funciona lo de Nevlucker lo hago así.

Sí, eso es lo que quiero que un mismo contacto pueda tener varios emails. Lo mismo haré para la información personal con el nombre de los hijos...

gracias a los 2


Título: Re: Error FOREIGN kEY sql server y c#
Publicado por: Novlucker en 9 Agosto 2010, 13:22 pm
SqlDataReader (http://msdn.microsoft.com/es-es/library/system.data.sqlclient.sqldatareader%28VS.80%29.aspx)

Saludos