Ir al contenido


Foto

[RESUELTO] Obtener un número autoincremental después de agregar el dato


  • Por favor identifícate para responder
38 respuestas en este tema

#21 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 20 febrero 2010 - 08:27

pues es lo mismo que yo hago y solo grabo en la 2da tabla en caso de que se cumpla la condicion


Bueno, es que en tu caso sabes cual es el csid, en mi caso yo no se cual es el ID, ese lo asigna la base de datos automáticamente y es un dato que desconozco hasta que el registro es agregado.

Salud OS
  • 0

#22 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 20 febrero 2010 - 08:32

Bueno, pues ya probé con el Open, funciona bien, agrega el registro sin problema, pero sigo sin poder acceder al campo RETURNING, probé con fields[0], con fieldbyname('ID') y nada, da error :(

Incluso intente con algo que vi por ahí (RETURNING ID INTO :ID) y no acepta esa declaración :(

Seguiré intentando, ya es por orgullo :p

Salud OS
  • 0

#23 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 20 febrero 2010 - 08:41

Hola Eliseo,
Yo había leído algo sobre RETURNING pero no lo suficiente como para entenderlo y saber el modo de leerlo. Como no uso Firebird 2.x no me tomé el tiempo de informarme... quizá en el release notes y/o en alguna otra documentación diga algo... será cuestión de investigar más a fondo.

Yo me quedé con esto que dijiste:

Perdón, sucede que ese número lo necesito para asignarlo en otra tabla inmediatamente después de haber agregado el registro.


¿Para que cosa lo necesitas amigo?
Porque eso, en principio, me huele a Triggers  ;)

Y si es viable la posibilidad del trigger, ese valor puede leerse desde NEW.ID u OLD.ID (depende del contexto en que se defina) ;) No se si me explico.

Saludos,
  • 0

#24 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 20 febrero 2010 - 08:42

Egostar el campo autoincrementable de la primera tabla se llama entradadatos y si te das cuenta ni siquiera aparece en el primer insert, debido a que la base de datos lo genera solo, ya que es autoincrementable y tiene un generador en la base de datos.

ese valor que ya se crea en el primer insert y que desconozco, lo llamo y se lo asigno al campo de la 2da tabla.

csid es otro campo, no tiene nada que ver con el autoincrementable
  • 0

#25 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 20 febrero 2010 - 08:49


Yo me quedé con esto que dijiste:

Perdón, sucede que ese número lo necesito para asignarlo en otra tabla inmediatamente después de haber agregado el registro.


¿Para que cosa lo necesitas amigo?
Porque eso, en principio, me huele a Triggers  ;)

Y si es viable la posibilidad del trigger, ese valor puede leerse desde NEW.ID u OLD.ID (depende del contexto en que se defina) ;) No se si me explico.


El asunto va así

Por un lado tengo un programa que recibe información de forma no supervisada, es decir, es un proceso automatizado, ese programa debe transferir un registro (dependiendo de ciertas características) a otra tabla del sistema donde otros módulos también van a agregar registros, el asunto es que solo necesito el ID que se genera en la tabla fuente y meterlo a la tabla destino.

¿ Me explico ?

Salud OS
  • 0

#26 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 20 febrero 2010 - 08:52

Egostar el campo autoincrementable de la primera tabla se llama entradadatos y si te das cuenta ni siquiera aparece en el primer insert, debido a que la base de datos lo genera solo, ya que es autoincrementable y tiene un generador en la base de datos.

ese valor que ya se crea en el primer insert y que desconozco, lo llamo y se lo asigno al campo de la 2da tabla.

csid es otro campo, no tiene nada que ver con el autoincrementable


jejeje, tal parece que les estoy dando la información a cuenta gotas :p, el asunto es que solo estoy utilizando un IBQuery Genérico para todos mis procesos y no dos como tú lo estás haciendo :$

Salud OS
  • 0

#27 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 20 febrero 2010 - 08:58

tampoco le veo la complicacion, si despues de insertar y verificar que cumple con las condiciones, le pasas en valor de ese campo a una variable y luego le pasas el valor de esa variable al campo de la otra tabla.

Eso es lo que veo desde mi optica caralistica osea novata.
  • 0

#28 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 20 febrero 2010 - 09:04

Déjame ver si logro entender... ¿entonces lo que buscas es insertar un "ID" en una tabla B una vez que se ha insertado cierto registro en la tabla A?

Si es eso entonces creo que no hace falta complicarselas. Un trigger AFTER INSERT TABLA A puede ejecuta la sentencia INSERT INTO hacia la tabla B con el ID en cuestión. Sólo hace falta pasarle como parámetro el NEW.ID

Si no se me entiende, lo explico nuevamente.

Saludos,
  • 0

#29 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 20 febrero 2010 - 09:06

Bueno, el uso de RETURNING me parece que no va a ser posible por lo menos con los IBX de mi Turbo Delphi, esto lo supongo al leer una de las notas de esta función:


3. If the RETURNING clause is present, then the statement is described as isc_info_sql_stmt_exec_procedure by the API (instead of isc_info_sql_stmt_insert), so the existing connectivity drivers should support this feature automatically.


Tendré que hacerlo con otra consulta, muchas gracias amigos. :(

Salud OS
  • 0

#30 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 20 febrero 2010 - 09:08

Déjame ver si logro entender... ¿entonces lo que buscas es insertar un "ID" en una tabla B una vez que se ha insertado cierto registro en la tabla A?

Si es eso entonces creo que no hace falta complicarselas. Un trigger AFTER INSERT TABLA A puede ejecuta la sentencia INSERT INTO hacia la tabla B con el ID en cuestión. Sólo hace falta pasarle como parámetro el NEW.ID

Si no se me entiende, lo explico nuevamente.

Saludos,


Bueno, el ID de esa tabla, pero además otros datos involucrados en el proceso automatizado, por eso es que no puedo hacerlo como lo sugieres amigo :)

Esto es muy fácil haciendo un select a la tabla para obtener el último registro, pero quería hacerlo de una sola pasada y no en dos, inicialmente pensé en un procedimiento almacenado, pero ya sabes, soy un vago :D :D :D

Salud OS
  • 0

#31 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 20 febrero 2010 - 09:28

Holis,

Ha, pues, si ese dichoso proceso automatizado está fuera del alcance de la base de datos ya no queda otra que lanzar una consulta. Ya sea que lo hagas consultando al generador o bien leyendo el último registro de la tabla.

Si el proceso está en la base de datos, si puede al menos en principio, en conseguirse con una cominación de SP y/o Triggers. ¡Y listo el pollo!

Saludos,
  • 0

#32 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 20 febrero 2010 - 09:30

Holis,

Ha, pues, si ese dichoso proceso automatizado está fuera del alcance de la base de datos ya no queda otra que lanzar una consulta. Ya sea que lo hagas consultando al generador o bien leyendo el último registro de la tabla.

Si el proceso está en la base de datos, si puede al menos en principio, en conseguirse con una cominación de SP y/o Triggers. ¡Y listo el pollo!

Saludos,


Tal vez si sea posible, de hecho no dudo que sea posible, pero es cosa de darme un tiempecillo, no se, hoy ya no creo hacerlo :p

Salud OS
  • 0

#33 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 21 febrero 2010 - 08:09

si quieres hacerlo en un solo query yo lo haria asi:



sql
  1. INSERT INTO tabla1 (id) VALUES (SELECT gen_id(GENERADOR, 0));
  2.  
  3. INSERT INTO tabla2 (id) VALUES (SELECT gen_id(GENERADOR, 1));



Fijate que el autoincrementable esta al final, asegurate que todo este en la misma transaccion es muy importante esto ultimo
  • 0

#34 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 21 febrero 2010 - 08:32

Hola

Pues si, al final use ese mismo concepto amigo Eduardo solo que utilice esto:



sql
  1. INSERT INTO tabla2 (id,.....) VALUES ( (SELECT MAX(id) FROM tabla1),......)



Pondré este hilo como [RESUELTO] con la reserva de encontrar solución a la propuesta de seoane. :)

Gracias a todos por su ayuda y comentarios. (y)

Salud OS
  • 0

#35 rmora

rmora

    Newbie

  • Miembros
  • Pip
  • 3 mensajes

Escrito 26 marzo 2010 - 11:46


Solo un pequeño detalle ¿estas usando ExecSQL o Open? Fijate que la sentencia SQL esta devolviendo datos y ExecSQL no es el método correcto, tienes que utilizar  Open


Ah vaya, pero..... en un INSERT INTO RETURNING puedo utilizar un Open en lugar del EXECSQL ??????

Ya lo pruebo :)

Salud OS



Hola egostar, tengo el mismo problema ademas de lo que comentas, en mi caso es una aplicacion punto de venta el cual tiene 10 usuarios recurrentes tomando pedidios, por lo tanto y para cuidar la integridad de los datos me parece mas acertado utilizar "INSERT INTO RETURNING", pero desconozco cual seria la sintaxis a utilizar.

Actualmente estoy utilizando este procedimiento mediante el cual le paso el string formado, pero evidentemente no me pasa el valor del campo generado.



delphi
  1. procedure EjecutaSQL (const Comando, DataBase : String); overload;
  2. var
  3.   qry : tQuery;
  4. begin
  5.   qry := tQuery.Create(nil);
  6.   qry.DatabaseName := DataBase;
  7.   qry.SQL.Add(Comando);
  8.   qry.ExecSQL;
  9.   qry.Destroy;
  10. end;



Mi pregunta es: Pudiste implementar la opcion del "INSERT INTO RETURNING"?? y como lo hiciste?
  • 0

#36 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 26 marzo 2010 - 12:12

Hola egostar, tengo el mismo problema ademas de lo que comentas, en mi caso es una aplicacion punto de venta el cual tiene 10 usuarios recurrentes tomando pedidios, por lo tanto y para cuidar la integridad de los datos me parece mas acertado utilizar "INSERT INTO RETURNING", pero desconozco cual seria la sintaxis a utilizar.

Actualmente estoy utilizando este procedimiento mediante el cual le paso el string formado, pero evidentemente no me pasa el valor del campo generado.


procedure EjecutaSQL (const Comando, DataBase : String); overload;
var
  qry : tQuery;
begin
  qry := tQuery.Create(nil);
  qry.DatabaseName := DataBase;
  qry.SQL.Add(Comando);
  qry.ExecSQL;
  qry.Destroy;
end;

Mi pregunta es: Pudiste implementar la opcion del "INSERT INTO RETURNING"?? y como lo hiciste?


Hola rmora, bienvenido a DelphiAccess, sientete como en casa :)

No pude utilizar el INSERT INTO RETURNING, lo que hice fué esto



delphi
  1.       SQL.Text := 'INSERT INTO Consumos(FOLIO,CONSEC,FECHA,HORA,REFERENCIA,HABITACION,' +
  2.                   'CARGO,IMPORTE,IVA,IMPUESTO1,IMPUESTO2,TOTAL,ABONO,STATUS,ACTIVO,'+
  3.                   'CORTECAJA,ID_USUARIO)'+
  4.                   ' VALUES (:FOLIO,:CONSEC,:FECHA,:HORA,(SELECT MAX(Folio) FROM Control),' +
  5.                   ':HABITACION,:CARGO,:IMPORTE,:IVA,:IMPUESTO1,:IMPUESTO2,:TOTAL,:ABONO,' +
  6.                   ':STATUS,:ACTIVO,:CORTECAJA,:ID_USUARIO)';



LO que utilicé fué esto



sql
  1. (SELECT MAX(Folio) FROM Control)



Con eso ya pude asignar el último ID de la tabla correspondiente. Espero te sirva.

Salud OS


  • 0

#37 rmora

rmora

    Newbie

  • Miembros
  • Pip
  • 3 mensajes

Escrito 26 marzo 2010 - 02:48

Hola rmora, bienvenido a DelphiAccess, sientete como en casa :)

No pude utilizar el INSERT INTO RETURNING, lo que hice fué esto



delphi
  1.       SQL.Text := 'INSERT INTO Consumos(FOLIO,CONSEC,FECHA,HORA,REFERENCIA,HABITACION,' +
  2.                   'CARGO,IMPORTE,IVA,IMPUESTO1,IMPUESTO2,TOTAL,ABONO,STATUS,ACTIVO,'+
  3.                   'CORTECAJA,ID_USUARIO)'+
  4.                   ' VALUES (:FOLIO,:CONSEC,:FECHA,:HORA,(SELECT MAX(Folio) FROM Control),' +
  5.                   ':HABITACION,:CARGO,:IMPORTE,:IVA,:IMPUESTO1,:IMPUESTO2,:TOTAL,:ABONO,' +
  6.                   ':STATUS,:ACTIVO,:CORTECAJA,:ID_USUARIO)';



LO que utilicé fué esto



sql
  1. (SELECT MAX(Folio) FROM Control)



Con eso ya pude asignar el último ID de la tabla correspondiente. Espero te sirva.

Salud OS


Gracias egostar,

Del mismo modo estoy utilizando tu sugerencia sin embargo por el volumen de transacciones me he encontrado con el problema de que dos usuarios entran prácticamente al mismo tiempo a este procedimiento asignandole el mismo "ID" a ambos. por lo tanto me sonaba mas acertado utilizar el "Returning".

Saludos
  • 0

#38 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 26 marzo 2010 - 03:00

Si, efectivamente, mi proceso no tiene problema porque es un solo programa el que accede a los datos, en tu caso si es necesario utilizar otro procedimient.

Salud OS
  • 0

#39 rmora

rmora

    Newbie

  • Miembros
  • Pip
  • 3 mensajes

Escrito 26 marzo 2010 - 03:05

Asi es egostar. Bueno esperare a ver si alguien me puede ayudar con este problema.

Gracias de todos modos.
  • 0




IP.Board spam blocked by CleanTalk.