Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Consultar tablas de dos bases de datos (https://www.clubdelphi.com/foros/showthread.php?t=84392)

Angel.Matilla 14-10-2013 11:00:29

Consultar tablas de dos bases de datos
 
Tengo dos bases de datos en Firebird y necesito conectar ambas para poder importar los datos de una a otra. Estoy usando C++ Builder con los elementos de conexión de interbase, pero no sé si se puede hacer algo así o tendré que exportar los datos.

Casimiro Notevi 14-10-2013 11:21:12

Usa 2 IBDatabase, 2 IBTransaction, 2 IBquery, cada uno a una BD.
Select en una e insert en la otra.

Angel.Matilla 14-10-2013 11:27:31

Sí, eso lo tengo claro, pero lo que no veo es como hacerlo. ¿Leo los datos de una con una select y los asigno a variables o puedo hacer directamente un cosa así?
Código SQL [-]
INSER INTO 'BD1:Tabla1' SELECT * FROM 'BD2:Tabla2'

Casimiro Notevi 14-10-2013 11:35:36

Entre BDs distintas no puedes hacerlo así, tendrías que hacerlo mediante un 'stored procedure' o 'trigger'.
Lo que puedes hacer es un bucle, algo más o menos así:

Código Delphi [-]
select * from bd1.tabla
while not bd1.tabla.eof do
begin
  insert into bd2.tabla values (bd1.tabla.campo1,bd1.tabla.campo2,...)
  bd2.post
  bd1.tabla.next
end

Angel.Matilla 14-10-2013 11:42:56

Muchas gracias. Probaré y ya os diré como ha ido.

Angel.Matilla 16-10-2013 13:43:49

No sé que hago mal. Estoy usando este código:
Código:

for (nItem = 0; nItem < slImporta->Count; nItem ++)
{
    cAux = "";

    if (!tColegio->InTransaction)
          tColegio->StartTransaction();

    Query->Close();
    qTemp->Close();
    qImporta->Close();
    qImporta->SQL->Text = "SELECT ";

    switch (StrToInt(slImporta->Strings[nItem]))
    {
          default:
              qTemp->SQL->Text = "SELECT RDB$FIELD_NAME FROM RDB$RELATION_FIELDS WHERE RDB$RELATION_NAME = :Tabla";
              qTemp->ParamByName("Tabla")->AsString = UpperCase(cTablas[nItem]);
              qTemp->Open();

              for (; !qTemp->Eof; qTemp->Next())
              {
                    qImporta->SQL->Text = qImporta->SQL->Text + qTemp->FieldByName("RDB$FIELD_NAME")->AsString.Trim() + ", ";
                    cAux = cAux + qTemp->FieldByName("RDB$FIELD_NAME")->AsString.Trim() + ", ";
              }

              qImporta->SQL->Text = StringReplace(qImporta->SQL->Text.SubString(1, qImporta->SQL->Text.LastDelimiter(",") - 1).Trim(), "\r\n", "", oReplace) + " FROM " + cTablas[nItem];
              cAux = cAux.SubString(1, cAux.LastDelimiter(",") - 1).Trim();

              Query->SQL->Text = "INSERT INTO " + cTablas[nItem] + " (" + cAux + ") VALUES (:" + StringReplace(cAux, ", ", ", :", oReplace) + ")";
              break;
          case 2:
              qImporta->SQL->Text = "SELECT DISTINCT Registro, Padre FROM Alumnos";
              Query->SQL->Text    = "INSERT INTO AluPad (Alumno, Padre) VALUES (:Alumno, :Padre)";
              break;
          case 3:
              qImporta->SQL->Text = "SELECT Entidad, Nombre FROM Bancos";
              Query->SQL->Text    = "INSERT ITNO Bancos (Entidad, Nombre) VALUES (:Entidad, :Nombre)";
              break;
          case 7:
              qImporta->SQL->Text = "SELECT A.Padre, B.Cuenta, B.Defecto FROM Alumnos A, Cuentas B WHERE A.Referencia||A.Recibo = B.Referencia ORDER BY Padre";
              Query->SQL->Text    = "INSERT INTO Cuentas (Padre, Cuenta, Defecto) VALUES (:Padre, :Cuenta, :Defecto)";
              break;
          case 14:
              qImporta->SQL->Text = "SELECT DISTINCT A.Padre_Ape, A.Padre_Nom, A.Registro, A.Padre_Sex, A.Padre_Dni, A.Domicilio, A.Cpostal, A.Poblacion, A.Provincia, A.Telefono, A.Correo, B.Domicilia, A.Padre_Obs FROM Padres A, Alumnos B WHERE A.Registro = B.Padre ORDER BY Padre_Ape, Padre_Nom, Registro";
              Query->SQL->Text    = "INSERT INTO Padres (Padre_Ape, Padre_Nom, Registro, Padre_Sex, Padre_Dni, Domicilio, Cpostal, Poblacion, Provincia, Telefono1, Correo, Domicilia, Padre_Obs) VALUES (:Padre_Ape, :Padre_Nom, :Registro, :Padre_Sex, :Padre_Dni, :Domicilio, :Cpostal, :Poblacion, :Provincia, :Telefono1, :Correo, :Domicilia, :Padre_Obs)";
              break;
    }

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

          Query->Close();
          for (int nParam = 0; nParam < Query->ParamCount; nParam ++)
              Query->Params->Items[nParam]->Value = qImporta->Fields->Fields[nParam]->Value;

          try
          {
              Query->ExecSQL();
              tColegio->Commit();
          }
          catch(...)
          {
              tColegio->Rollback();
          }
    }
}

Vamos por partes:
  1. cAux es una variable AnsiString.
  2. cTablas es un vector AnsiString donde guardo los nombres de las tablas a importar.
  3. Query y qTemp son dos TIBQuery que apuntan a una de las dos bases de datos.
  4. qImporta es un TIBQuery que apunta a la otra base de datos.
Cuando ejecuto este código se montan bien los querys y no hay ningún error, hasta que sale del switch. Cuando pasa por el break me da este mesaje de error:
Cita:

class EIBInterBaseError with message 'invalid transaction handle (expecting explicit transaction start)'
¿Qué estoy haciendo mal?

Angel.Matilla 16-10-2013 14:04:57

No he dicho nada. Estaba definiendo mal una transacción. Disculpad.


La franja horaria es GMT +2. Ahora son las 08:36:29.

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