Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Duda tuplas con misma clave primaria (https://www.clubdelphi.com/foros/showthread.php?t=89911)

Man0261 27-02-2016 21:32:18

Duda tuplas con misma clave primaria
 
Hola.

Tengo una nueva duda acerca de la inserción de datos. Tengo que insertar muchas tuplas a las cuales accedo a través de otras tablas. El caso es que yo tengo dos tuplas que comparten clave primaria, y por lo tanto, al insertar todos los datos de golpe, me da error ya que se viola la clave primaria. Tengo que insertar la tupla que tenga uno de sus atributos mayor al de la otra tupla. Me gustaría saber como puedo hacer eso...

Gracias y un saludo.

(Uso oracle)

AgustinOrtu 27-02-2016 22:14:25

No entiendo, la idea es juntar en una tabla A lo que esta en las Tablas B y C; luego entre B y C hay claves primarias duplicadas?

Man0261 28-02-2016 11:53:00

Creo que no me expliqué. Yo tengo que transferir los datos de una tabla que contiene dos tuplas erróneas ya que violan la clave primaria. Entonces tengo que insertar en la nueva tabla sólo una de esas dos tuplas. La que en uno de sus atributos, tiene un valor mayor respecto a la otra.

ecfisa 28-02-2016 13:44:26

Hola.
Cita:

Empezado por Man0261 (Mensaje 502788)
Yo tengo que transferir los datos de una tabla que contiene dos tuplas erróneas ya que violan la clave primaria. Entonces tengo que insertar en la nueva tabla sólo una de esas dos tuplas. La que en uno de sus atributos, tiene un valor mayor respecto a la otra.

Si no entendí mal podes hacer:
Código SQL [-]
INSERT INTO DESTINO (ID, ATRIBUTO /*, ...*/)
SELECT T1.ID, T1.ATRIBUTO /*, ... */
FROM ORIGEN T1
WHERE T1.ATRIBUTO = (SELECT MAX(T2.ATRIBUTO) 
                     FROM ORIGEN T2
                     WHERE T2.ID = T1.ID)
Donde la columna ID representa la clave primaria y ATRIBUTO la columna de mayor valor a seleccionar.

Saludos :)

Man0261 28-02-2016 13:49:07

Hola, gracias!!

T1.ID qué significa? y T2?

Solo hay dos tablas. La de origen, y la tabla donde quiero almacenar las cosas..

Man0261 28-02-2016 15:15:51

Cita:

Empezado por Man0261 (Mensaje 502790)
Hola, gracias!!

T1.ID qué significa? y T2?

Solo hay dos tablas. La de origen, y la tabla donde quiero almacenar las cosas..

Tengo que hacer algo asi como agrupar las tuplas por el atributo por el que quiero insertar en función de él. He pensado en agruparlos por orden según esa variable, y luego insertarlas tuplas solo si antes no había metida una tupla con la misma clave primaria. No sé si esto es lo que me pones en el código o no pero me he hecho un lío porque me has puesto como 3 tablas si no he visto bien, y solo influyen 2 tablas.. De todas formas no sabría hacer en lenguaje SQL lo que he expuesto

ecfisa 28-02-2016 15:31:04

Hola.
Cita:

Empezado por Man0261 (Mensaje 502790)
Hola, gracias!!

T1.ID qué significa? y T2?

Solo hay dos tablas. La de origen, y la tabla donde quiero almacenar las cosas..

Son alias, uno por cada tabla. T1 para la tabla ORIGEN y T2 para la tabla DESTINO.

Algunos gestores podrían requerir la sintáxis completa:
Código SQL [-]
SELECT * FROM NOMBRE_TABLA AS NOMBRE_ALIAS 
...

Saludos :)

Man0261 28-02-2016 16:09:40

Pero me has puesto la tabla ORIGEN T1, ORIGEN T2 Y DESTINO

ecfisa 28-02-2016 16:23:35

Hola.

DESTINO es la tabla donde se hará la inserción resultado de las selecciones. T1 y T2 son ambos alias de la tabla origen pero pertenecen a distintas selecciones.

Te convendría profundizar más sobre SQL, algunos enlaces:
Saludos :)

AzidRain 28-02-2016 20:05:44

Tienes que realizar un análisis de las tuplas antes de intentar insertarlas. Es decir, tienes que verificar si hay tuplas con misma clave primaria y dado el caso definir cual será la que deberás insertar. Una vez analizadas y procesadas entonces sí mandárselas al motor de BD. Si lo haces directamente en la BD se daría el siguiente supuesto:

Código:

  Se inserta tupla 1 de tabla A en tabla B
  Se toma siguiente tupla de tabla A
  clave de tupla 2 de tabla A ya existe en tabla B?
      [NO] insertar tupla 2 de tabla A en tabla B
      [SI] x propiedad de tupla 2 de tabla A es mayor que la que tiene la misma clave en tabla B ?
            [NO] No insertar nada y saltar a siguiente tupla de tabla A
            [SI] Eliminar tupla existente de tabla B e insertar la nueva tupla en tabla B
  Continuar con siguiente tupla de tabla A y repetir ciclo

Depende donde quieras colocar la lógica de negocio de tu aplicacion. En cualquier caso deberás usar una transacción para garantizar que si algo falla no te deje a medias alguna tabla.

AgustinOrtu 28-02-2016 22:12:44

Yo sigo sin entender

No podes tener una clave primaria duplicada, ningun motor de BD te puede permitir eso, ya que sino se pierde el chiste de la PK

El valor de la "PK", la que esta duplicada, tiene un valor real o es ficticio?

Es decir, es un id autogenerado, o es algo que tiene valor dentro de la logica del negocio? Por ej. es un numero de socio que esta impreso en las tarjetas (por decir algo)

AzidRain 28-02-2016 23:25:39

Lo que nuestro amigo busca es que pueda "sustituir" un registro ya existente y con un id (PK) definido por otro con la misma id siempre y cuando el sustituto cumpla ciertas reglas. Es algo así como en mi refri tengo un cartón de leche, (su id es "leche") y mi refrigerador está programado para solo poder guardar un cartón de leche. Encuentro una marca diferente (tiene otras características) que la que ya tengo guardada, entonces tengo que decirle a mi refrigerador que si intento guardar un cartón de leche éste debe ser mejor (en alguna de sus propiedades que ahi mismo defino) que el que ya se encuentra almacenado. Si es así entonces, se desecha el que ya estaba y se guarda el nuevo cartón.

AgustinOrtu 29-02-2016 03:12:38

Ahora sí, crei que era un problema de merge

Lo querés resolver con sql o por código Delphi?

Quizá hacerlo por código sea más fácil, flexible, pero obviamente más lento

AgustinOrtu 29-02-2016 03:16:42

Parece ser que Oracle soporta una sintaxis que podría servir en tu caso

Es como un "try-except"

Revisa este enlace

Neftali [Germán.Estévez] 29-02-2016 10:17:54

Cita:

Empezado por Man0261 (Mensaje 502788)
Yo tengo que transferir los datos de una tabla que contiene dos tuplas erróneas ya que violan la clave primaria. Entonces tengo que insertar en la nueva tabla sólo una de esas dos tuplas. La que en uno de sus atributos, tiene un valor mayor respecto a la otra.

Ordena la tabla por este atributo ("en uno de sus atributos, tiene un valor mayor respecto a la otra");
A la hora de insertar, se insertará primero, el que tiene el atributo mayor (que es lo que necesitas).
El resto de inserciones fallarán por clave duplicada.


La franja horaria es GMT +2. Ahora son las 13:29:48.

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