Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MySQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=21)
-   -   como resuelvo una relacion N a N? (https://www.clubdelphi.com/foros/showthread.php?t=44381)

newgeek 05-06-2007 09:05:20

como resuelvo una relacion N a N?
 
Como va, soy bastante nuevo en esto de mysql y la programacion y queria pedir una ayuda, resulta que tengo un ejercicio que hacer y no logro entender como podria solucionase.

Lo resumere lo mas posible, resulta que tengo 3 tablas de las cuales 1 es el detalle de las otras 2 osea esta en medio de una relacion "N a N"
Código SQL [-]
create table tabla1(
id int not null primary key auto_increment,
descr char(50)
)TYPE=MyISAM,auto_increment=1;

create table tabla2(
id2 int not null primary key auto_increment,
descr char(50)
)TYPE=MyISAM,auto_increment=1;

create table tabla_detalle(
idd int not null primary key auto_increment,
id int not null references tabla1(id),
id2 int not null references tabla2(id2)
)TYPE=MyISAM,auto_increment=1;

Cual seria la forma correcta de tratar estas relaciones? de modo que la tabla_detalle se actualice sola, me imagino que al meter un nuevo registro de en las 2 primeras tablas de alguna forma se deveria guardar el id para que luego se actualice la tercera tabla, creo le llaman trigger.

Bueno espero que me ayuden :(

Neftali [Germán.Estévez] 05-06-2007 11:02:40

Bueno, lo normal es que crees tú el registro de la tercera tabla, ya que es el que define la relación entre las otras dos.
Podrías llegar a automatizar ese proceso, pero sólo en casos muy concretos. Piensa que a veces un registro de tabla1 no tiene porqué tener relación con ninguno de tabla2 o tener relación con varios de la segunda tabla y al revés también.

Lepe 05-06-2007 11:57:02

Hola newgeek.

En primer lugar quiero darte la Bienvenida al foro y una merecida felicitación, son muy pocos los usuarios que se informan como usar las etiquetas sql y explicar detalladamente su problema en su primer mensaje en el foro.

Teniendo en cuenta lo dicho por Neftali, podrías crear un procedimiento almacenado que se encargue de la inserción:

Código SQL [-]
CREATE PROCEDURE Inserta_detalles(
    IDtabla1 INTEGER,
    IDtabla2 INTEGER)
AS
begin
  INSERT INTO Tabla3 ( null, id, id2) 
  values ( :IDtabla1, :IDtabla2)
end

puedes llamar a este SP de dos formas:
- Con un query:
Código Delphi [-]
  query1.sql.text := 'execute procedure inserta_detalles( :tabla1, :tabla2)';
  query1.parambyname('tabla1').ASInteger := strtoint(edit1.text); // id de la tabla1
  query1.parambyname('tabla2').ASInteger := strtoint(edit2.text); // id de la tabla2
  query1.ExecSql; // hacemos la inserción.

- Con un componente Store Procedure (lo tendrás en la paleta de delphi, será un TIBStoreProcedure, TMDOStoreProcedure, etc), en el inspector de objetos añades el nombre del procedimiento, y asignas los parámetros en tiempo de ejecución, (mira la ayuda, lo explicará mejor que yo ;)).

Como habrás visto, en el cuerpo de Inserta_detalles, se envía un null a su clave primaria, para que no obtengas error, deberás tener un trigger before insert para la tabla 3:
Código SQL [-]
CREATE TRIGGER tabla3_BI FOR tabla3
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW.idd IS NULL) THEN
    NEW.idd = GEN_ID(GEN_tabla3_IDD,1);
END

GEN_tabla3_idd será un generador creado a tal efecto.

Saludos

roman 05-06-2007 17:29:01

No entiendo bien. ¿Cuál es la ventaja de hacerlo así, en lugar de ejecutar directamente una sentencia INSERT?

// Saludos

Lepe 05-06-2007 20:34:18

Tienes razón. Quizás le sirva como ejemplo de un SP :D

Inicialmente preguntaba como hacerlo "desde un trigger", así que puse el ejemplo del Store Procedure, para que viera como hacerlo desde el lado servidor.

El ejemplo del query, sería para aplicarlo desde el lado cliente, aprovechando que tiene el SP creado.

Quizás con un TxxStoreProcedure si obtenga ventaja en cuanto a líneas de código, ya que solo tiene que ejecutarlo (1 sola línea de código). Pero sabemos que en realidad no se ahorra mucho, el propio componente TxxStoreProcedure debe crearse en ejecución también ;).

Saludos

roman 05-06-2007 20:40:09

Yo de esto no sé gran cosa, pero me llamó la atención un procedimiento almacenado, un disparador y un generador para una mera inserción. Pero la verdad es que, como dices, es un muy buen ejemplo para entender de esto.

// Saludos

Lepe 06-06-2007 16:28:19

ok, tu mandas:

Código Delphi [-]
 query1.sql.text := 'insert into tabla3 (idd, id, id2) ' + 
              'values(GEN_ID(GEN_tabla3_IDD,1), :tabla1, :tabla2)';
  query1.parambyname('tabla1').ASInteger := strtoint(edit1.text); // id de la tabla1
  query1.parambyname('tabla2').ASInteger := strtoint(edit2.text); // id de la tabla2
  query1.ExecSql; // hacemos la inserción.

.... vale, dejo ya los desvaríos :D

Saludos


La franja horaria es GMT +2. Ahora son las 10:10:52.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi