Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-07-2005
Avatar de marceloalegre
[marceloalegre] marceloalegre is offline
Miembro Premium
 
Registrado: abr 2005
Ubicación: Mar del Plata - Argentina
Posts: 448
Poder: 20
marceloalegre Va por buen camino
Post Es simple! pero estoy complicado!!!

Estoy complicado con algo simple....

necesito saber como puedo hacer para:
tengo una base de datos que contiene la tabla cliente
clientes tiene cod_cli nombre direccion telefono

existe el siguiente dato cargado en un registro
cod_cli=1 (para esto uso un generator, asi que se carga solo...)
nombre=juan perez
direccion=calle x 123
telefono=555123456

quiero ingresar un nuevo registro basando en los datos del anterior:
cod_cli=2 esto no tengo problemas uso el generator
nombre=juan perez
direccion=calle x 123
telefono=555123456
(o sea,, quiero utilizar los mismos datos exatos, quiero copiarlos del registro anterior...)
como hago para que cuando hago el insert,,, en mis values le diga "que escriba lo del registro anterior??

me podria alguien dar un ejemplo de esto??
Muchas GRacias!!!!
Responder Con Cita
  #2  
Antiguo 22-07-2005
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
A ver si te sirve este truco de Trucomania:
Código Delphi [-]
 procedure TForm1.Button2Click(Sender: TObject);
  
 type 
      {Tipos para array dinámico de variants}
      TRecuerda = array[0..0] of variant;
      PRecuerda = ^TRecuerda;
 var 
    Recuerda:PRecuerda;
    n:integer;
    Campos:integer;
 begin 
    {Reservamos memoria para el array}
    Campos:=Table1.FieldCount;
    GetMem(Recuerda, Campos * SizeOf(variant));
  
    {Vamos al ultimo registro}
    Table1.Last;
    {Recordamos los campos}
    for n:=0 to Table1.FieldCount-1 do 
    begin 
      Recuerda^[n]:=Table1.Fields[n].AsVariant;
    end; 
  
    {Añadimos un registro}
    Table1.Append;
    {Lo rellenamos}
    for n:=0 to Table1.FieldCount-1 do 
    begin 
      Table1.Fields[n].AsVariant:=Recuerda^[n];
    end; 
    {Lo grabamos}
    Table1.Post;
  
    {Liberamos memoria}
    FreeMem(Recuerda, Campos * SizeOf(Variant));
 end;

Un Saludo.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #3  
Antiguo 22-07-2005
Avatar de marceloalegre
[marceloalegre] marceloalegre is offline
Miembro Premium
 
Registrado: abr 2005
Ubicación: Mar del Plata - Argentina
Posts: 448
Poder: 20
marceloalegre Va por buen camino
me he expresado mal disculpa, si he visto este excelente truco,,, el tema es que tengo que hacerlo en sql,, porque todo esto debe ir en un stored prodecure... debe ser simple imagino, pero mi inexperiencia en sql es muy grande



Gracias!
Responder Con Cita
  #4  
Antiguo 22-07-2005
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Trata con este Insert

Código SQL [-]
insert into cliente (nombre, direccion, telefono)
  select nombre, direccion, telefono from cliente
    where cod_cli = (select max(cod_cli) from cliente)


Saludos...
Responder Con Cita
  #5  
Antiguo 25-07-2005
Avatar de marceloalegre
[marceloalegre] marceloalegre is offline
Miembro Premium
 
Registrado: abr 2005
Ubicación: Mar del Plata - Argentina
Posts: 448
Poder: 20
marceloalegre Va por buen camino
Post

Estoy observando que esto obtiene el maximo codigo de cliente, eso no seria util al caso porque el anterior no quiere decir que sea el maximo nro ... yo solamente quiero crear un nuevo registro, poner un nuevo cod de cliente, y reaprovechar, o sea, copiar, los datos del registro anterior.

Muchas Gracias!
Responder Con Cita
  #6  
Antiguo 25-07-2005
Avatar de hector.roma
hector.roma hector.roma is offline
Miembro
 
Registrado: jul 2005
Ubicación: a caballo entre Galicia y Portugal
Posts: 58
Poder: 20
hector.roma Va por buen camino
A que te refieres con el anterior...

Generalmente cuando insertas un registro nuevo, lo haces con el máximo código de la tabla... entonces el anterior al nuevo será MAX(Cod_Cli) ya que el nuevo es MAX(Cod_Cli) + 1 (aunque uses un generador supongo).

Cita:
Siguiendo el estilo de maeyanes:
Código SQL [-]
insert into cliente (nombre, direccion, telefono)
select nombre, direccion, telefono from cliente
where cod_cli = (select max(cod_cli) from cliente) /* el anterior */
Te devolverá un nuevo registro con los datos del último registro.

Si sabes cual es el código del registro anterior ...
Código SQL [-]
insert into cliente (nombre, direccion, telefono)
select nombre, direccion, telefono from cliente
where cod_cli = 345 /* por ejemplo ese es el anterior */

Especifica a que te refieres con el anterior... y podremos ayudarte mejor.

Última edición por hector.roma fecha: 25-07-2005 a las 14:47:46. Razón: Correción
Responder Con Cita
  #7  
Antiguo 25-07-2005
Avatar de marceloalegre
[marceloalegre] marceloalegre is offline
Miembro Premium
 
Registrado: abr 2005
Ubicación: Mar del Plata - Argentina
Posts: 448
Poder: 20
marceloalegre Va por buen camino
Thumbs down

me refiero a eso, con el ultimo, exactamente, has intepretado bien,, pero te comento que este programa ya estaba hecho, y si se elimina un cliente reaprovecha el cod de cliente!! cosa muy mala! entonces por eso no puedo usar un max... porque el nro de cliente mas alto no quiere decir el ultimo!

imaginate que la base de datos es de mas de 2 gb de info..
Responder Con Cita
  #8  
Antiguo 25-07-2005
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
El SQL para inserción que puse, si te fijas bien, no asigna el código de cliente puesto que en tu primer mensaje especificaste que no había problema en eso...
Cita:
cod_cli=2 esto no tengo problemas uso el generator
...lo único que hace la sentencia es tomar los demás datos del último registro, que en el caso sería el registro anterior...
Cita:
(o sea,, quiero utilizar los mismos datos exatos, quiero copiarlos del registro anterior...)
como hago para que cuando hago el insert,,, en mis values le diga "que escriba lo del registro anterior??
Así que no veo el porque no puedas usarlo.


Saludos...
Responder Con Cita
  #9  
Antiguo 25-07-2005
Avatar de hector.roma
hector.roma hector.roma is offline
Miembro
 
Registrado: jul 2005
Ubicación: a caballo entre Galicia y Portugal
Posts: 58
Poder: 20
hector.roma Va por buen camino
Algo se me escapa...

Tienes los datos del cliente anterior en un registro...
  • si está en memoria es asignarlos a un nuevo cliente y listo. Para ello puedes usar delphi, stored procedures, o lo que quieras.
  • Que el registro no está en memoria, entonces tienes que conocer la llave de tu registro, recuperar los datos que te interesan y asignarselo de la misma forma que antes.
  • Que la llave es ese número entero que no identifica nada, entonces
    Código SQL [-]
    SELECT Cod_Cli FROM Clientes WHERE Nombre=@Nombre AND ...
    e introduces el resto de parámetro que identifican de forma única tu cliente. Cuando lo hagas, tendras el Cod_Cli que te interesa, y las soluciones anteriores te vadrán.
  • Ninguna de estas opciones te vale ... no nos dejes hacer suposiciones y comenta claramente tu problema, procurando no olvidarte de nada.
En cualquier caso seguiremos aquí para ayudar...
Responder Con Cita
  #10  
Antiguo 26-07-2005
Avatar de marceloalegre
[marceloalegre] marceloalegre is offline
Miembro Premium
 
Registrado: abr 2005
Ubicación: Mar del Plata - Argentina
Posts: 448
Poder: 20
marceloalegre Va por buen camino
Cool

Ya entendí la idea, les agradesco muchisimo tanto a Marcos como a Hector por la paciencia en la explicacion del tema es cuestion.

ya esta todo funcionando..

Muchas gracias!!
Responder Con Cita
  #11  
Antiguo 11-10-2005
lento manu lento manu is offline
Miembro
 
Registrado: oct 2004
Posts: 29
Poder: 0
lento manu Va por buen camino
Invalid Variant Type

Siento pediros ayuda sobre este trucazo que editó Marcos Zorrilla. Estoy compilando en D6 con el BDE y al asignar el primer valor de tipo text en el campo 0 del registro Table1.Fields[n].AsVariant se colapsa el for por "Invalid Type Variant"
Cita:
Empezado por marcoszorrilla
A ver si te sirve este truco de Trucomania:
Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
 
type 
{Tipos para array dinámico de variants}
TRecuerda = array[0..0] of variant;
PRecuerda = ^TRecuerda;
var 
Recuerda:PRecuerda;
n:integer;
Campos:integer;
begin 
{Reservamos memoria para el array}
Campos:=Table1.FieldCount;
GetMem(Recuerda, Campos * SizeOf(variant));
 
{Vamos al ultimo registro}
Table1.Last;
{Recordamos los campos}
for n:=0 to Table1.FieldCount-1 do 
begin 
Recuerda^[n]:=Table1.Fields[n].AsVariant;
//error de Invalid Variant Type
end;  
...
FreeMem(Recuerda, Campos * SizeOf(Variant));
end;
Lo increible es que al poner el punto de interrupción en la línea, leo el valor del Table1.Fields[0].asVariant='NOMBRE' (pasa un simple valor tipo string), y por tanto, creo q es el Recuerda^[0] no acepta este valor.Buscando en Gogle por "EVariantBadVarTypeError", q acompaña el mensaje del compilador, encuentro esta página http://qc.borland.com/wc/qcmain.aspx?da=42 y selcciono el enlace 5239 (http://qc.borland.com/wc/qcmain.aspx?d=5239) donde parece q la solución esta en rescribir la unidad Variants.pas. después del login, menciona un atachement, pero no hay enlace para descargarlo.
¿Tenéis alguien esta unidad corregida?
¿No habría otra solución?
Si podéis tener alguna sugerencia... GRACIAS A TODOS
...quizás sería preferible abrir un nuevo hilo...
Responder Con Cita
  #12  
Antiguo 12-10-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Hombre, está sacado de trucomania, que esperabas .
Así queda mejor, nos quitamos punteros y reserva de memoria.

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
 
type 
{Tipos para array dinámico de variants}
TRecuerda = array of variant;
var 
Recuerda:TRecuerda;
n:integer;
Campos:integer;
begin 
{Reservamos memoria para el array}
  Campos:=Table1.FieldCount;
  SetLength(Recuerda,Campos);
 
{Vamos al ultimo registro}
Table1.Last;
{Recordamos los campos}
for n:=0 to Table1.FieldCount-1 do 
begin 
Recuerda[n]:=Table1.Fields[n].AsVariant;

{Añadimos un registro}
    Table1.Append;
    {Lo rellenamos}
    for n:=0 to Table1.FieldCount-1 do 
    begin 
      Table1.Fields[n].AsVariant:=Recuerda[n];
    end; 
    {Lo grabamos}
    Table1.Post;
// no tenemos que liberar la memoria, al ser una variable local, se libera
// al salir
  end;  

end;

[saludos] y más [/saludos]
Responder Con Cita
  #13  
Antiguo 12-10-2005
lento manu lento manu is offline
Miembro
 
Registrado: oct 2004
Posts: 29
Poder: 0
lento manu Va por buen camino
¡Que es fista!

Jod..., Lepe, q es fiesta. Te me has adelantada porque es exactamente como lo he solucionado. Pero las gracias te las mereces igualmente o más. Yo lo había escrito así:
Código Delphi [-]
procedure TfmPal.ToolButton3Click(Sender: TObject);
 var
    Recuerda : array of variant;
    n:integer;
 begin
    {Reservamos memoria para el array}

    SetLength(Recuerda,Table1.FieldCount);
    {Vamos al ultimo registro}
    Table1.Last;
    {Recordamos los campos}
    for n:=0 to Table1.FieldCount-1 do
    begin
      Recuerda[n]:=Table1.Fields[n].AsVariant;
    end;
    {Añadimos un registro}
    Table1.Append;
    {Lo rellenamos}
    for n:=0 to Table1.FieldCount-1 do
    begin
      Table1.Fields[n].AsVariant:=Recuerda[n];
    end;
    {Lo grabamos}
    Table1.Post;
    Recuerda:=nil;
end;
El nil era por si acaso, pero ya me queda claro con tu comentario q es redundante. También he quitado la asignación Type, y me funciona estupendo. Ya lo estoy implementando en mi componente del DBX.pas, de modo q al crear un nuevo registro (a través del evento del DBNavigator BeforeAction, ya q el TTable está en mi DataModule y no puedo sobrescribir su BeforeInsert (q ya está escito desde el DM), asigno los valores actuales a este array de variants), para poder insertar los valores de cada campo iguales al anterior por medio de F4 (en mi caso: antiguo usuario Magic). Aún me falta cuando el DBeditor es un DBLookUpComboBox. Pero como también soy usuario de mis programas, me lo voy a agradecer mucho.
Pero no entiendo porque en el código del que extrajimos este procedimiento, se cuelga en la Variant.pas, y no en la asignación de los punteros. Desde luego así es mucho más legible y comprensible, pero veo código por ahí q con los punteros consiguen todo. No te molestes en contestar aquí lo de los punteros, porque realmente no pertenecia a este hilo SQL, ya mi pregunta anterior. Cuando pueda ya buscaré por aquí a ver q entiendo, y si me lanzo a usarlos algo más. Gracias por tus ayudas, ... piensate lo de la fotillo, aunque la CCC también vale!
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 01:07: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
Copyright 1996-2007 Club Delphi