Curso de C++ Builder


Acceso a bases de datos

TDatabase



El componente TDatabase permite controlar las conexiones a una base de datos. Aunque su uso no es estrictamente necesario, hay ciertas operaciones para las que resulta imprescindible:

Conexiones persistentes con bases de datos

La propiedad KeepConnections de TDatabase se utiliza para controlar cómo se manejan las conexiones con las bases de datos cuando se cierra un dataset. Si KeepConnections está a false, cuando se cierra el último dataset, la conexión con la base de datos se pierde y habrá que reiniciarla la próxima vez que se abra otro dataset, lo que consumirá una cantidad considerable de tiempo y, si no hacemos nada para evitarlo, volverá a solicitar la clave de acceso del usuario.

Establecimiento de la conexión [Login]

El componente TDatabase también permite controlar el login de una forma automática:

  • Estableciendo la propiedad LoginPrompt a false y fijando explícitamente los parámetros de la conexión.

    Desde el código
    Database->AliasName = "Oracle";
    Database->DatabaseName = "MiDB";
    Database->Params->Values["user name"] = "scott";
    Database->Params->Values["password"]  = "tiger";
    Table->DatabaseName = Database->DatabaseName;
    Table->TableName = "CUSTOMER";
    Table->Open();
    
    Desde el inspector de objetos
    En el editor de listas asociado a la propiedad Params:
    USER NAME=scott
    PASSWORD=tiger
    

  • Interceptando el evento OnLogin, el cual se genera cada vez que se ha de establecer una conexión cuando la propiedad LoginPrompt está a true.

    void __fastcall ...::DatabaseLogin
        (TDatabase *Database, TStrings *LoginParams)
    {
      LoginParams->Values["user name"] = "scott";
      LoginParams->Values["password"]  = "tiger";
    }
    

    Schema cache

    void __fastcall ...::DatabaseLogin
        (TDatabase *Database, TStrings *LoginParams)
    {
      ...
    
      // Schema cache
    
      AnsiString S;
      S.SetLength(255);
      
      int L = GetTempPath(255, S.c_str());
      
      if (S.IsPathDelimiter(L)) L--;
    
      S.SetLength(L);
      Database1->Params->Values["ENABLE SCHEMA CACHE"] = "TRUE";
      Database1->Params->Values["SCHEMA CACHE DIR"] = S;
    }
    

    Control de Transacciones

    Otro uso más del componente TDatabase (puede que el más importante) es el control explícito de las transacciones con la base de datos.

    Una transacción es una colección de operaciones sobre la base de datos (inserciones, modificaciones o eliminaciones de registros) que ha de realizarse de forma atómica.

    Una transacción con la base de datos se inicia explícitamente llamando al método StartTransaction(). Las modificaciones realizadas sobre la base de datos no se harán efectivas hasta que se invoque al método Commit(). Si se quiere cancelar la transacción en curso hay que recurrir al método Rollback(), lo cual hará que las operaciones efectuadas en la transacción sean ignoradas. Mediante la propiedad TransIsolation se puede establecer la el nivel de aislamiento entre distintas transacciones. El nivel tiRepeatableRead (lecturas repetibles) será siempre el deseable, aunque con determinados servidores SQL sólo se llega a tiCommitedRead ("lecturas comprometidas") y las bases de datos de escritorio (tipo Paradox, dBase o Access) sólo permiten tiDirtyRead.

    Una transferencia bancaria
    TLocateOptions Opt;
    
    // Iniciar la transacción
    
    Database->StartTransaction();
    
    try {
    
        if (! Table->Locate("Cliente", cliente1, Opt))
           DatabaseError("No existe el primer cliente", 0);
    
        Table->Edit();
        Table->FieldValues["Saldo"] -= importe;
        Table->Post();
    
        if (! Table->Locate("Cliente", cliente2, Opt))
           DatabaseError("No existe el segundo cliente", 0);
    
        Table->Edit();
        Table->FieldValues["Saldo"] += importe;
        Table->Post();
    
        // Confirmar la transacción
    
        Database->Commit();
    
    } catch(Exception&) {
    
        // Cancelar la transacción
    
        Database->Rollback();
        Table->Refresh();
        throw;
    }
    

    Cancelar los cambios realizados desde el ultimo commit/rollback

    void CancelarCambios (TDatabase* ADatabase)
    {
      ADatabase->Rollback();
    
      for (int i = ADatabase->DataSetCount - 1; i >= 0; i--)
          ADatabase->DataSets[i]->Refresh();
    }
    


    Índice de la sección