Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Actualizar tabla con datos de otra tabla mediante UPDATE (https://www.clubdelphi.com/foros/showthread.php?t=50763)

Rockin 27-11-2007 22:22:24

Actualizar tabla con datos de otra tabla mediante UPDATE
 
Es posible realizar en firebird la actualizacion de una tabla con los datos de otra, estan en la misma BD, seria correcto asi?
Código SQL [-]
uptade ventas_new set nombre= ventas_old.nombre from ventas_old where id = ventas_old.id

Es correcto, o fallo en algo.
Es que lo estoy haciendo desde EMS SQL Manager 2005 for InterBase & Firebird y me da error.

Saludos.

maeyanes 27-11-2007 22:35:55

La consulta correcta sería:

Código SQL [-]
update ventas_new a set a.nombre = (select b.nombre from ventas_old b where b.id = a.id)


Saludos...

Rockin 27-11-2007 22:44:29

Gracias, mañana probaremos a ver que tal.

jhonny 27-11-2007 22:50:15

Cita:

Empezado por maeyanes (Mensaje 248836)
La consulta correcta sería:

Código SQL [-]
update ventas_new a set a.nombre = (select b.nombre from ventas_old b where b.id = a.id)

Me temo que de esa manera conseguiremos una consulta muy lenta y ademas el b.nombre quedara repetido en toda la tabla ventas_new, para evitar eso habra que agregar la condición adecuada fuera de la subconsulta.

maeyanes 27-11-2007 22:53:47

mmm por que va a quedar repetido?

jhonny 27-11-2007 23:10:50

Cita:

Empezado por maeyanes (Mensaje 248841)
mmm por que va a quedar repetido?

Código SQL [-]
update ventas_new a set a.nombre = (select b.nombre from ventas_old b where b.id = a.id)

Bueno, fraccionemos el ejercicio un poco haciendo una especie de "prueba de escritorio"...

Por un lado tenemos

Código SQL [-]
update ventas_new a set a.nombre =

Esa parte de la consulta esta esperando un valor, que puede ser cualquiera, en nuestro caso es...

Código SQL [-]
(select b.nombre from ventas_old b where b.id = a.id)

- Ahora bien, si hacemos un ejercicio mental de quitar la subconsulta e imaginarnos que nos devuelve un valor cualquiera, por ejemplo "Jhonny", obtendriamos la siguiente consulta, (Que en ultimas es lo que haria cualquier motor, suponiendo que unicamente me devolvera un solo registro en todos los casos)...

Código SQL [-]
update ventas_new a set a.nombre = 'Jhonny'

Como podemos ver no hay una condición where donde le indique al motor cual es el registro para actualizar, de manera que los actualizara todos ;).

jhonny 27-11-2007 23:40:42

Bueno maeyanes, acabo de hacer una prueba para corroborar el asunto en (FB2.1 Beta 2 - Dialecto3) y me he dado cuenta que vos tenes la razón, aunque aún no cabe dentro de mi logica, definitivamente el efecto es el que vos haz comentado :).

jhonny 27-11-2007 23:52:27

Ahhh, Claro¡¡¡ :D, ¿Como es que no lo habia visto asi? :), lo que hace el update es ir "recorriendo" los registros y asignandoles el valor correspondiente, si ponemos un where "recorrera" solo los que esten dentro de la condición, en este caso como no hemos puesto un where los recorrera todos, asignandoles el valor de la subconsulta, que basandome en el ejemplo anterior no siempre tendremos como resultado 'Jhonny', ya que dicha subconsulta tiene su propia condición basada en los datos de la tabla ventas_new (Que es la que queremos actualizar) y traera un valor diferente dependiendo del registro de donde este "ubicado" el cursor al momento de actualizar... Caramba¡¡¡ que descachada me pegue :D, ahora si que comprendo este asunto con una mejor logica :D.

Rockin 28-11-2007 11:34:22

Gracias maeyanes, lo he probado y me va de puta madre me has ahorrado un monton de tiempo. Cuando vengas por Málaga tienes barra libre pagada.

Saludos

jhonny 28-11-2007 14:02:37

Aún asi, creo que en FireBird esta haciendo falta algo (Si es que ya no existe y no me he dado cuenta), ¿Que sucederia si queremos actualizar varios campos de esta manera?, abria que hacer lo siguiente:

Código SQL [-]
update ventas_new a set a.nombre = (select b.nombre from ventas_old b where b.id = a.id), a.apellido = (select b.apellido from ventas_old b where b.id = a.id)

Esto debe ser muy lento... deberia existir una manera de hacerlo diferente... como creo que lo he visto en otros motores, algo como:

Código SQL [-]
update ventas_new a set a.nombre = b.nombre, a.apellido=b.apellido 
from inner join ventas_old b on (b.id = a.id)

No se, quizá es una idea loca y hasta sin sentido, como quizá sea algo que he observado en algún otro lugar, pero creo que deberia existir.

maeyanes 28-11-2007 15:10:53

Hola...

Yo siempre he usado el update de esa forma y siempre me ha resultado bien... por eso me extrañó que me dijeras que se repetiría lo mismo en todos los registros... :p

Y si, en algunas ocasiones puede ser lento... sobre todo si son tablas muy grandes...



Saludos...

Chris 28-11-2007 15:26:14

Cita:

Empezado por jhonny (Mensaje 248984)
Código SQL [-]update ventas_new a set a.nombre = b.nombre, a.apellido=b.apellido
from inner join ventas_old b on (b.id = a.id)

Creo que jhonny está equivocado, o en al final soy yo, porque eso quedaría así:

Código SQL [-]
update ventas_new a set 
a.nombre, a.apellido
values
(Select b.nombre, b.apellido from ventas_old b where (a.id = b.id))
de esta forma solo haríamos una sóla consulta anidada.

jhonny 28-11-2007 15:29:22

Cita:

Empezado por maeyanes (Mensaje 249002)
Hola...

Yo siempre he usado el update de esa forma y siempre me ha resultado bien... por eso me extrañó que me dijeras que se repetiría lo mismo en todos los registros... :p

Bueno, como dicen por ahí, "La practica hace al maestro" :)

jhonny 28-11-2007 15:41:24

Cita:

Empezado por D&W (Mensaje 249007)
Creo que jhonny está equivocado, o en al final soy yo, porque eso quedaría así:

Código SQL [-]
update ventas_new a set 
a.nombre, a.apellido
values
(Select b.nombre, b.apellido from ventas_old b where (a.id = b.id))
de esta forma solo haríamos una sóla consulta anidada.

Eso, algo asi estaria bien... repito (si es que no existe ya), en el Insert tambien deberia existir algo por el estilo, aunque la verdad es que siempre que he necesitado algo asi, hago un procedimiento almacenado.

maeyanes 28-11-2007 15:55:24

Hola!

Es posible esa sintaxis en Firebird?

Por que hasta ahora no he visto ningún documento donde indique que si es posible, y haciendo unas pruebas con Firebird 2, obtuve un error...



Saludos...

maeyanes 28-11-2007 16:01:26

Cita:

Empezado por jhonny (Mensaje 249020)
Eso, algo asi estaria bien... repito (si es que no existe ya), en el Insert tambien deberia existir algo por el estilo, aunque la verdad es que siempre que he necesitado algo asi, hago un procedimiento almacenado.

Bueno... en el insert si es posible hacer algo así:

Código SQL [-]
/* Ambas tablas tienen los mismos campos con los mismos nombres */
insert into Tabla1 (select * from Tabla2)

/* Usando nombres de campos */
insert into tabla1 (campo1, campo2) (select campo1, campo2 from Tabla2)


Saludos...

jhonny 28-11-2007 18:27:29

Cita:

Empezado por maeyanes (Mensaje 249031)
Hola!

Es posible esa sintaxis en Firebird?

Por que hasta ahora no he visto ningún documento donde indique que si es posible, y haciendo unas pruebas con Firebird 2, obtuve un error...



Saludos...


Ese es el punto... no se puede hacer, pero sería interesante que se pudiera :).

En cuanto a lo de la sintaxis que nos muestras sobre el insert, pues te cuento que acabo de hacer una prueba con FB 2.0.3

como la que indicas, pero desafortunadamente con la primero consulta me muestra el siguiente error:

Código SQL [-]
insert into TablaPrueba (select * from TablaPrueba2) /*Tienen la estructura igual*/

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 1, column 26.
select.

y con la segunda, lo siguiente:

Código SQL [-]
insert into TablaPrueba (codigo, descripcion) (select codigo, descripcion from TablaPrueba2)

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 1, column 48.
(.


Sinceramente, recuerdo vagamente que alguna vez hice algo como lo que indicas, pero como ya he comentado, siempre que necesito estas cosas he usado un procedimiento almacenado por lo que ya no recuerdo si la vez que lo hice fue con FB u otro motor :(.

maeyanes 28-11-2007 19:09:13

Bueno... la verdad es que lo hice de memoria... :D

Revisando la documentación...

Código SQL [-]
insert into Tabla1 (campo1, campo2, campo3)
  select campo1, campo2, campo3 from Tabla2



Saludos...

jhonny 28-11-2007 19:15:42

Cita:

Empezado por maeyanes (Mensaje 249069)
Bueno... la verdad es que lo hice de memoria... :D

Revisando la documentación...

Código SQL [-]
insert into Tabla1 (campo1, campo2, campo3)
  select campo1, campo2, campo3 from Tabla2

Jojojo, es cierto, de nuevo tienes razón :), de hecho tambien es cierto lo otro, asi:

Código SQL [-]
insert into Tabla1 select * from Tabla2

Una solución por el estilo debe tener lo del Update con una sola subconsulta que he planteado mas arriba :), pero ni la encuentro y/o ni la recuerdo :D.


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

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