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)
-   -   Problema al grabar con UNION 2 TABLAS (https://www.clubdelphi.com/foros/showthread.php?t=75374)

pmtzg 18-08-2011 04:28:47

Problema al grabar con UNION 2 TABLAS
 
hola amigos
deseo consultar con ustedes el siguiente problema que tengo

estoy uniendo 2 bases de datos por medio de un query y union
creo mis tablas y creo los index y clave primaria
para pasarlo a una tabla de Firebird 2.1

si lo hago asi como les cuento en la parte del IBtable1.post
me marca un error por que se llegan a duplicar el registro
pero le meti 2 TRY este es el codigo:


Código Delphi [-]
nr:=nr+1    // para que no se duplique el campo: num_reg
while not Query1.Eof do
begin

  st3.Caption :='registro no.: '+inttostr(Query1.RecNo)+' -'+inttostr(Query1.RecordCount)+ modul;
   IBTable1.Append;
   for I := 0 to query1.Fields.Count - 1 do
        begin
             IBTable1.FieldByName('NUM_REG').AsInteger := nr;
             IBTable1.Fields[i].Value := query1.Fields[i].Value;
          
              try              {x si hay un error de reg.duplicado }
                IBTable1.Post;
              except                     
              end; 
            try
              Query1.Next;
              Gg1.Progress:= Query1.RecNo;
              nr := nr+1;
            finally
            end; 

end; {  while}


pero aun así me marca errores de duplicidad como PRIMARY KEY
etc

si al crear mis tablas no creo index y key primary no tengo obiamente
problemas de grabar al transferir los registros

alguien me podria orientar como poder manejar este error y que siga
grabando mis demas registros
gracias por su apoyo

pmtzg 18-08-2011 07:48:46

problema
 
el mensaje que o error que me lanza es el siguiente:

Código Delphi [-]
raised exption class EIBInterbaseError with message  attempt to store duplicate
 VAlue  (visible to active transaction ) in unique index  'mitabla'


segun yo es por que estoy tratando de insertar una dato o un campo que ya existe en mi tabla

pero no hayo la manera de que siga la ejecución de mi programa o siga grabando registros y saltar este error



Espero q me puedan ayudan ayudar gracias

newtron 18-08-2011 08:48:25

Hola.

Creo que el problema que tienes es el siguiente

Código Delphi [-]
for I := 0 to query1.Fields.Count - 1 do
  begin
    IBTable1.FieldByName('NUM_REG').AsInteger := nr;
    IBTable1.Fields[i].Value := query1.Fields[i].Value;

en este código asignas por un lado el valor nuevo al campo "NUM_REG" pero en la siguiente linea al empezar desde el campo 0 de la tabla vuelves a asignar el mismo campo con el valor antiguo.

Suponiendo que el campo "NUM_REG" es el primero deberías de empezar en el for por el 1 o chequear antes de asignarlo que no es ese campo si empiezas desde el 0, por ejemplo:
Código Delphi [-]
for I := 0 to query1.Fields.Count - 1 do
  begin
    IBTable1.FieldByName('NUM_REG').AsInteger := nr;
    If IBTable1.Fields[i].Name<>'NUM_REG' then
      IBTable1.Fields[i].Value := query1.Fields[i].Value;

Saludos

pmtzg 18-08-2011 09:00:40

gracias Amigo
pero probe pero no es por ahi }


solo quisiera saber si ya le meti un tye except, que puedo hacer para que no separe mi proceso salte este registro o error y siga insertando mas registros


Aguien me pueda dar una manita mas , de verdad q no le hayo

gracias

ecfisa 18-08-2011 14:06:41

Hola pmtzg.

Cita:

segun yo es por que estoy tratando de insertar una dato o un campo que ya existe en mi tabla
Estas bién orientado: Attempt to store duplicate value (visible to active transactions) in unique index. ;)

Cita:

pero probe pero no es por ahi
Sin embargo, al igual que newtron, estoy totalmente convencido de que sí es por ahí... :)



Hace una semana te sugerí lo mismo con tablas Paradox: mensaje #2, en la línea:
Cita:

For i := 1 to ViejaTablaParadox.Fields.Count -1 do // i=1 para respetar el campo_ID
Y en otro hilo posterior lo mismo hace oscarac: mensaje #2, en la línea:
Cita:

for I := 1 to query2.fields.Count - 1 do


No es muy eficiente por que realiza una asignación innecesaria, pero como sospecho que la ubicación de 'NUM_REG' puede no ser la primera...
Código Delphi [-]
var
  i: Integer;
  NumReg: Integer;
begin
  Query1.Open;
  IBTable1.Open;
  NumReg:= 1;
  while not Query1.Eof do
  begin
    IBTable1.Append;
    for i:= 0 to Query1.FieldCount -1 do
      IBTable1.Fields[i].Value:= Query1.Fields[i].Value;
    IBTable1.FieldByName('NUM_REG').AsInteger:= NumReg;
    IBTable1.Post;
    Query1.Next;
    Inc(NumReg);
  end;
  IBTable1.Close;
  Query1.Close;
end;
El código funciona. (probado)



Cita:

solo quisiera saber si ya le meti un tye except, que puedo hacer para que no se pare mi proceso salte este registro o error y siga insertando mas registros
Un consejo: No utilices try/except para enmascarar excepciones, es muy mala práctica.

Saludos.

pmtzg 18-08-2011 16:10:45

hola mi estimado ecfisa
antes que nada gracias por tu tiempo y tu paciencia
mira esta es la estructura de mi tabla :

Código Delphi [-]
CREATE TABLE FACT04 (
    NUM_REG     INTEGER NOT NULL,
    TIP_REG     VARCHAR(1),
    TIP_DOC     VARCHAR(1),
    CVE_DOC     VARCHAR(7),
    CVE_CLPV    VARCHAR(5),
    MOSTRA      VARCHAR(1),
    STATUS      VARCHAR(1),
    CVE_VEND    VARCHAR(5),
    CVE_PEDI    VARCHAR(7),
    FECHA_DOC   TIMESTAMP,
    FECHA_ENT   TIMESTAMP,
    FECHA_VEN   TIMESTAMP,
    CAN_TOT     DOUBLE PRECISION,
    IMP_TOT1    DOUBLE PRECISION,
    IMP_TOT2    DOUBLE PRECISION,
    DES_TOT     DOUBLE PRECISION,
    DES_FIN     DOUBLE PRECISION,
    COM_TOT     DOUBLE PRECISION,
    OBS_COND    VARCHAR(25),
    OBS_ENVI    INTEGER,
    OBS_FACT    INTEGER,
    OBS_CLIE    INTEGER,
    NUM_PART    SMALLINT,
    NUM_ALMA    SMALLINT,
    ACT_CXC     VARCHAR(1),
    ACT_COI     VARCHAR(1),
    BLOQ        SMALLINT,
    CVE_CONS    VARCHAR(5),
    STRNOGUIA   VARCHAR(15),
    STRMODOENV  VARCHAR(20),
    DOCANTSIG   VARCHAR(9),
    NUM_MONED   VARCHAR(2),
    TIPCAMB     DOUBLE PRECISION,
    NOPAGOS     SMALLINT,
    CVE_ZONA    VARCHAR(6),
    TIPO_FLET   VARCHAR(5),
    COSTOFLET   DOUBLE PRECISION,
    IMPUEFLET   DOUBLE PRECISION,
    RETENFLET   DOUBLE PRECISION,
    FECHA_ENV   TIMESTAMP,
    FECHAELAB   TIMESTAMP,
    USUARIO     SMALLINT,
    IMP_TOT3    DOUBLE PRECISION,
    IMP_TOT4    DOUBLE PRECISION,
    PRIMERPAGO  DOUBLE PRECISION,
    RFC         VARCHAR(15),
    CTLPOL      INTEGER,
    ESCFD       VARCHAR(1),
    AUTORIZA    INTEGER,
    FOLIO       INTEGER,
    SERIE       VARCHAR(10),
    TIPDOCANT   VARCHAR(1),
    AUTOANIO    VARCHAR(4)
);




/******************************************************************************/
/*                                Primary Keys                                */
/******************************************************************************/

ALTER TABLE FACT04 ADD PRIMARY KEY (NUM_REG);


/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/

CREATE UNIQUE INDEX FACF04 ON FACT04 (TIP_DOC, FECHA_DOC, CVE_DOC);
CREATE UNIQUE INDEX FACT04 ON FACT04 (TIP_DOC, CVE_DOC);
CREATE UNIQUE INDEX FCLI04 ON FACT04 (CVE_CLPV, TIP_DOC, CVE_DOC);


aqui te dira como es la tabla y te comento partieron en 2 esta tabla ahora la tengo que unir para sacar algunos reportes pero te soy muy honesto aqui si me atore por el error que te comente hice los cambios que me sugeriste pero aun no tengo resultado

ojala pueda seguir contando con tus comentarios

nota: no es la unica tabla todavia tengo otra donde estan los auxiliares de esta y tengo mas de 1 millon de registros

mil gracias

ecfisa 18-08-2011 16:18:06

Hola pmtzg.

Cita:

CREATE UNIQUE INDEX FACF04 ON FACT04 (TIP_DOC, FECHA_DOC, CVE_DOC);
CREATE UNIQUE INDEX FACT04 ON FACT04 (TIP_DOC, CVE_DOC);
CREATE UNIQUE INDEX FCLI04 ON FACT04 (CVE_CLPV, TIP_DOC, CVE_DOC);
Ha... ahora sí.

El problema no te lo dá el índice primario sino los que has declarado como UNIQUE y al estar así declarados, no pueden existir dos valores iguales en dichos campos.

Tendrías que revisar los valores duplicados o quitar esa declaración para realizar la copia.

Saludos.

pmtzg 18-08-2011 17:20:12

asi es mi estmado ecfisa
pero una pregunta mas aprovecando tu bondad

fijate que estas tablas de paradox ya estan definidas, yo trabajo con ellas con una copia

cuando las creo las creo la tabla e index asi :

Código Delphi [-]
IBTable1.FieldDefs.Assign(table1px.FieldDefs);
IBTable1.IndexDefs.Assign(table1px.IndexDefs);
IBTable1.CreateTable;

tomo la estructura de la tabla de paradox y creo mi tabla en firebird
si al crear mi tabla omito esto:

Código Delphi [-]
IBTable1.IndexDefs.Assign(table1px.IndexDefs);

no creo los index en donde se declara el UNIQUE

si despues de crear mi tabla como te mostre y edito para la creación de los
index con que me recomiendas tu crearlos

lo intente con IBscripts, pero me marca error
gracias

ecfisa 18-08-2011 19:02:28

Hola pmtzg.

En Firebird, para agregar una Key UNIQUE:
Código SQL [-]
ALTER TABLE TUTABLA ADD CONSTRAINT PK_TUTABLA_UNIQUE1 UNIQUE(TU_CAMPO)

Para quitarla:
Código SQL [-]
ALTER TABLE TUTABLA DROP CONSTRAINT PK_TUTABLA_UNIQUE1

Pero si las key UNIQUE tienen que quedar y tenés repetición de valores en los campos, no te va a permitir hacerlo. Si es 'unico' no puede haber duplicidad.

Saludos.

pmtzg 18-08-2011 19:24:27

fijate que usare IBSQL1 para craEAR MI INDEX

lo meto a un ciclo

creo la primera tabla ... ok
creo su index IBSQL! ... ok

Código Delphi [-]
IBSQL1.sql.text :='create index CCLIEDX2 on clie04 (cclie); ';

elijo otra tabla

creare la tabla2 pero al momento de decirle

Código Delphi [-]
IBtable1.createtable ;

me lanza el error haciendo referencia de anterior index que cree, ejemplo

Código Delphi [-]
unsuccessful metadata update unknown columns in index  CCLIEDX2

pero antes ya habia declarado este parrafo:

Código Delphi [-]
IBSQL1.sql.text :=' '+
'CREATE  INDEX FACF04 ON FACT04 (TIP_DOC, FECHA_DOC, CVE_DOC); '+
' CREATE  INDEX FACT04 ON FACT04 (TIP_DOC, CVE_DOC);  '+  
' CREATE  INDEX FCLI04 ON FACT04 (CVE_CLPV, TIP_DOC, CVE_DOC); ';


que hice mal , si la primera tabla se creo y su index muy bien hasta vacie los datos de paradox a firebird

tendria que decirle algo mas a mi codigo para que no me pase esto ???

ecfisa 18-08-2011 19:49:20

Hola.

Realmente no te estoy comprendiendo, no entiendo como estas creando tus tablas.

Si previamente habías echo algo así:
Código Delphi [-]
 with IBSQL1.SQL do
  begin
    Add('CREATE TABLE FACT04 (');
    Add('NUM_REG     INTEGER NOT NULL,');
    Add('TIP_REG     VARCHAR(1),');
    Add('TIP_DOC     VARCHAR(1),');
    ...
    Add('CVE_DOC     VARCHAR(7));');
  end;
  IBSQL1.ExecQuery;

Para que luego haces:
Código Delphi [-]
  IBTable1.CreateTable;
si la tabla ya ha sido creada.

Un saludo.

pmtzg 18-08-2011 19:53:38

abro tabla Paradox y base de datos Firebird

Código Delphi [-]
IBTable1.FieldDefs.Assign(table1px.FieldDefs);
// IBTable1.IndexDefs.Assign(table1px.IndexDefs);  // omiti esto para arreglar lo de los index 
IBTable1.CreateTable;

de este modo creo para evitar la captura de los campos
pero me he atorado a la hora de crear los index ya modificados
eso es lo q me pasa


La franja horaria es GMT +2. Ahora son las 16:12:06.

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