Ir al contenido


Foto

PostgreSql + ADO Autoincrementales


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

#1 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 28 enero 2013 - 09:33

Saludos.

En la empresa se ha estado desarrollando la aplicación usando Sql Server 2008 Express + ADO + Intraweb hasta el momento se los resultados son los esperados.

Pero (siempre un pero  :@) existe un cliente que tiene PostgreSql como BD para sus desarrollos, mi jefe ha estado haciendo la prueba de la aplicación atacando PostgreSql; el resultado es que todo funciona bien hasta el momento salvo los campos autoincrementales,  el caso es que el registro se salva pero no se refresca el campo autoincremental en la aplicación.

La tabla posee el trigger y el objeto secuencial; cuando se manda a grabar el registro se ve en la BD el valor del campo incremental pero en la aplicación para poder visualizar el valor se debe cerrar y abrir el DataSet.

¿Existe alguna manera de obtener el valor sin tener que cerrar y abrir el DataSet después de almacenado el registro?
  • 0

#2 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 28 enero 2013 - 09:49

Prueba con esto:



delphi
  1. uses
  2. ...
  3.  
  4. AdoInt;
  5. .....
  6.  
  7. with ADOQuery1 do
  8.   begin
  9.     UpDateCursorPos; 
  10.     RecordSet.Resync(adAffectCurrent, adResyncAllValues);
  11.   end;


  • 0

#3 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 28 enero 2013 - 11:43

Saludos.

@Wilson, gracias por tu respuesta, supongo que eso sera después de haber realizado el Post. ¿Cierto?

No puedo probarlo directamente ya que no poseo la instalación de la BD, pero ya les comentare como me fue.
  • 0

#4 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 28 enero 2013 - 11:45

supongo que eso sera después de haber realizado el Post. ¿Cierto?


Si, amigo Rolphy.

Saludos.
  • 0

#5 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 16 mayo 2013 - 02:47

Saludos.

Retomando el tema, estoy haciendo las pruebas con el código expuesto por Wilson; pero estoy obteniendo un mensaje de error:
"Class EOleException with message 'Key value for this row was changed or deleted at the data store. The local row is now deleted'".

La estructura es la siguiente:
CREATE TABLE sys.entrada_salida_inventario
(
  entrada_salida_inventarioid integer NOT NULL DEFAULT nextval('sys."ENTRADA_SALIDA_INVENTARIO_ENTRADA_SALIDA_INVENTARIOID_seq"'::regclass),
  companiaid integer NOT NULL,
  divisionid integer NOT NULL,
  localidadid integer NOT NULL,
  tipo_documentoid integer NOT NULL,
  almacenid integer NOT NULL,
  numero integer NOT NULL,
  fecha timestamp without time zone NOT NULL,
  fecha_vencimiento timestamp without time zone,
  suplidorid integer,
  ncf_codigo character varying(11),
  numero_comprobante_fiscal character varying(8),
  referencia character varying(30),
  concepto character varying(100),
  condicion_pagoid integer,
  clase_costo_gastoid integer,
  monedaid integer NOT NULL,
  tasa numeric(18,2) NOT NULL,
  indicador_autorizada character varying(1) NOT NULL,
  indicador_actualizada character varying(1) NOT NULL,
  total_bruto numeric(18,4) NOT NULL,
  total_descuento numeric(18,4) NOT NULL,
  total_subtotal numeric(18,4) NOT NULL,
  total_itbis numeric(18,4) NOT NULL,
  total_neto numeric(18,4) NOT NULL,
  indicador_entrada_diario character varying(1) NOT NULL,
  estado character varying(1) NOT NULL,
  indicador_impresa character varying(1),
  CONSTRAINT "PK_ENTRADA_SALIDA_INVENTARIO" PRIMARY KEY (entrada_salida_inventarioid )
)
WITH (
  OIDS=FALSE
);
ALTER TABLE sys.entrada_salida_inventario
  OWNER TO admbon;
GRANT ALL ON TABLE sys.entrada_salida_inventario TO admbon;
GRANT ALL ON TABLE sys.entrada_salida_inventario TO sys_user WITH GRANT OPTION;

  • 0

#6 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 16 mayo 2013 - 03:07

Hola amigo, Cuándo me he enfrentado a esta situación lo que hago es cerrar y abrir nuevamente el dataset....

tal vez no sea lo mejor pero funciona...
  • 0

#7 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 16 mayo 2013 - 03:09

Hola amigo, Cuándo me he enfrentado a esta situación lo que hago es cerrar y abrir nuevamente el dataset....

tal vez no sea lo mejor pero funciona...

Saludos.

Solo por saber (no lo tomes a mal), ¿Es lo que haces en tus desarrollos habituales con PostgreSQL?.

El asunto es que no sabría como obtener el ultimo ID del secuencial, este tema me tiene bastante fustrado.....


  • 0

#8 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 16 mayo 2013 - 03:23


Hola amigo, Cuándo me he enfrentado a esta situación lo que hago es cerrar y abrir nuevamente el dataset....

tal vez no sea lo mejor pero funciona...

Saludos.

Solo por saber (no lo tomes a mal), ¿Es lo que haces en tus desarrollos habituales con PostgreSQL?.

El asunto es que no sabría como obtener el ultimo ID del secuencial, este tema me tiene bastante fustrado.....


No amigo, por lo general en mis desarrollos nunca abro tablas ni ejecuto consultas, todo lo hago a través de procedimientos almacenados. 

Si estás trabajando directamente en las tablas lamento no poder ayudarte más, pero si te es de ayuda puedes darle una leida al siguiente artículo:

http://www.postgresq...s-sequence.html
  • 0

#9 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 16 mayo 2013 - 04:58

Retomando el tema, estoy haciendo las pruebas con el código expuesto por Wilson; pero estoy obteniendo un mensaje de error:
"Class EOleException with message 'Key value for this row was changed or deleted at the data store. The local row is now deleted'".


Parece que el método no funciona con PostgreSql, intenta cambiando el segundo parámetro del método Resync por adResyncUnderlyingValues, a ver que pasa.

Si no te funciona, he pensado en una solución a partir de la lectura del enlace que provee Poliburro, podrías no asignar explícitamente el valor del campo auto-incremental, en su defecto harías uso de la función NEXTVAL que incrementa la secuencia y devuelve un número seguro (por fuera de la transacción) y le pasarías el valor devuelto por la función al dataset antes de llamar a Post.

Un saludo.
  • 0

#10 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 20 mayo 2013 - 09:27

Saludos.

Encontre una solución, me parece que la mas viable, para mi pequeño problema.

Ante todo cabe resaltar que la aplicación "es multi base de datos", dicho esto, la solución consiste en estos pasos:
  • Crear en Run Time los campos de manera persistentes, no puede ser en Design Time porque es "multi base de datos".
  • Al campo (o los campos) del tipo incremental asignar en la propiedad AutoGenerateValue el valor arAutoInc también podría ser arDefault analizando bien el caso
  • Al componente TCustomADODataSet asignar las siguientes propiedades:
    a) CursorLocation := clUseServer
    b) CursorType := ctKeyset;

Con todo lo anterior el mismo ADO se encarga de refrescar los valores de los campos autoincrementales sin necesidad de nuestra intervención.

Lo único que no sé a ciencia cierta, es si el rendimiento de la aplicación se vera afectado por el cambio de la propiedad CursorLocation que pasa de clUseClient a clUseServer.

Gracias a todos por el apoyo!!!
  • 0

#11 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 20 mayo 2013 - 09:38

Saludos.

Encontre una solución, me parece que la mas viable, para mi pequeño problema.

Ante todo cabe resaltar que la aplicación "es multi base de datos", dicho esto, la solución consiste en estos pasos:

  • Crear en Run Time los campos de manera persistentes, no puede ser en Design Time porque es "multi base de datos".
  • Al campo (o los campos) del tipo incremental asignar en la propiedad AutoGenerateValue el valor arAutoInc también podría ser arDefault analizando bien el caso
  • Al componente TCustomADODataSet asignar las siguientes propiedades:
    a) CursorLocation := clUseServer
    b) CursorType := ctKeyset;

Con todo lo anterior el mismo ADO se encarga de refrescar los valores de los campos autoincrementales sin necesidad de nuestra intervención.

Lo único que no sé a ciencia cierta, es si el rendimiento de la aplicación se vera afectado por el cambio de la propiedad CursorLocation que pasa de clUseClient a clUseServer.

Gracias a todos por el apoyo!!!


Gracias por compartirnos  la solución amigo mio...
  • 0




IP.Board spam blocked by CleanTalk.