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)
-   -   Un query que se cierra solo (https://www.clubdelphi.com/foros/showthread.php?t=84436)

Angel.Matilla 18-10-2013 13:23:11

Un query que se cierra solo
 
Estoy usando Firebird con C++ 6. Tengo este código con dos TIBQuery:
Código:

Query->Close();
Query->SQL->Text = "INSERT INTO Cuentas (Padre, Cuenta, Defecto)
VALUES (:Padre, :Cuenta, :Defecto)";

qTemp->Close();
qTemp->SQL->Text = "SELECT DISTINCT A.Padre, B.Cuenta, B.Defecto
FROM ALU_TEMP A, CUE_TEMP B WHERE A.Referencia||A.Recibo = B.Referencia";
qTemp->Open();

for (; !qTemp->Eof; qTemp->Next())
{
    if (!tColegio->InTransaction)
          tColegio->StartTransaction();

    Query->Close();
    Query->ParamByName("Padre")->AsInteger  = qTemp->FieldByName("Padre")->AsInteger;
    Query->ParamByName("Cuenta")->AsString  = qTemp->FieldByName("Cuenta")->AsString;
    Query->ParamByName("Defecto")->AsInteger = qTemp->FieldByName("Defecto")->AsInteger;
    try
    {
          Query->ExecSQL();
          tColegio->Commit();
    }
    catch(...)
    {
          tColegio->Rollback();
    }
}

Hace el primer insert pero cuando debería avanzar al segundo registro de lectura me dice que que no porque el dataset está cerrado (Cannot perform this operation on a closed dataset). Si fuera cierto no debría leer ni el primer registro.

He probado, en vez de un bucle, a hacer un INSERT masivo:
Código SQL [-]
INSERT INTO Cuentas (Padre, Cuenta, Defecto) 
SELECT DISTINCT A.Padre, B.Cuenta, B.Defecto FROM ALU_TEMP A, CUE_TEMP B WHERE A.Referencia||A.Recibo = B.Referencia

y me da un error de violacion de claves (la tabla está indexada por padre y cuenta).

¿A alguien se le ocurre alguna idea?

Casimiro Notevi 18-10-2013 18:17:04

Creo que el problema es que cuando guardas un registro debes hacer post, ya que el commit lo cierra.

ecfisa 18-10-2013 18:25:59

Cita:

Empezado por Angel.Matilla (Mensaje 468561)
Hace el primer insert pero cuando debería avanzar al segundo registro de lectura me dice que que no porque el dataset está cerrado (Cannot perform this operation on a closed dataset). Si fuera cierto no debría leer ni el primer registro.

Hola Angel.

El método Commit() almacena todas las operaciónes pendientes de la transacción actual y la cierra, por lo que deberías habrirla nuevamente si deseas continuar con las operaciones.
Así mismo, el método Rollback(), cancela todas las operaciones pendientes de la transacción actual y la cierra. También deberías abrirla nuevamente si deseas continuar operando con ella.

Existe la alternativa de usar CommitRetaining() y RollbackRetaining() que respectivamente almacenan y cancelan las operaciones, pero mantienen abierta la transacción actual.

Saludos :)

Edito: Como dijo Casimiro arriba. (no lo había visto... :o)

Angel.Matilla 18-10-2013 18:38:44

Gracias a los dos. Ahora mismo lo pruebo.

Angel.Matilla 18-10-2013 19:20:48

Cita:

Empezado por ecfisa (Mensaje 468575)
Existe la alternativa de usar CommitRetaining() y RollbackRetaining() que respectivamente almacenan y cancelan las operaciones, pero mantienen abierta la transacción actual.

Perfecto. Lo que no acabo de entender es por qué no fuciona el INSERT masivo, pero dado que ya se ha solucionado.

Casimiro Notevi 18-10-2013 20:00:03

Cita:

Empezado por Angel.Matilla (Mensaje 468578)
Perfecto. Lo que no acabo de entender es por qué no fuciona el INSERT masivo, pero dado que ya se ha solucionado.


Creo recordar que la sentencia es así:

Código SQL [-]
insert into tbCuentasB (select * from tbCuentasA)

Angel.Matilla 19-10-2013 10:34:40

No. El problema tiene que ser otro porque en ese mismo proceso de carga tengo otra tabla con la sintaxis que yo ponía:
Código SQL [-]
INSERT INTO Tabla1 SELECT * FROM Tabla2
y no me da error; además, el error es un problema de índices. No obstante ya está solucionado con el bucle.

Casimiro Notevi 19-10-2013 11:05:32

Entonces es que en la tabla origen tienes 2 registros con el mismo valor y en la de destino no están permitidos repetidos.
Problema en los datos.

Angel.Matilla 19-10-2013 11:06:39

Efectivamente.


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

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