TDataSet es la clase superior de la jerarquía de clases definida en C++Builder para definir conjuntos de datos. TTable, TQuery y TStoredProc son casos particulares de conjuntos de datos. De hecho, la mayoría de las propiedades, métodos y eventos que se utilizan en estas clases están definidas realmente en TDataSet, en TBDEDataSet o en TDBDataSet:
Propiedad | Descripción |
---|---|
Active | Abre el conjunto de datos cuando se establece a true y lo cierra cuando se fija a false. |
Bof | Devuelve true si el cursor está en el primer registro del conjunto de datos. |
CachedUpdates | Cuando está a true, las actualizaciones se mantienen en la caché de la máquina del cliente hasta que el programador los envíe al servidor. Cuando está a false, todos los cambios realizador en los conjuntos de datos se pasan automáticamente a la base de datos. |
CanModify | Determina si el usuario puede editar el conjunto de datos o no. |
DataSource | El componente TDataSource asociado. |
DatabaseName | El nombre de la base de datos con la que se está trabajando. |
Eof | Devuelve true cuando el cursor está llega al final del conjunto de datos. |
FieldCount | Es el número de columnas o campos del conjunto de datos. |
Fields | Columnas del conjunto de datos: array de objetos de tipo TField. |
FieldValues | Devuelve el valor de un campo especificado en el registro actual. |
Found | Indica si una operación de búsqueda ha tenido éxito o no. |
Modified | Indica si el registro actual ha sido modificado. |
RecNo | El número de registro actual en el dataset. |
RecordCount | Devuelve el número de registros en el dataset. |
State | Devuelve el estado actual del conjunto de datos. |
UpdatesPending | Cuando está a true, el buffer del conjunto de datos contiene modificaciones de los datos que aún no han sido enviadas a la base de datos. |
Método | Descripción |
---|---|
Append() | Crea un registro vacío y lo añade al final del conjunto de datos. |
AppendRecord() | Añade un registro especificado al final del conjunto de datos. |
ApplyUpdates() | Envía a la base de datos cualquier actualización en caché que estuviese pendiente. La escritura no se realiza realmente hasta que se invoca al método CommitUpdates(). |
Cancel() | Cancela cualquier modificación en el registro actual si no ha sido enviada con Post(). |
CancelUpdates() | Cancela cualquier actualización en caché que estuviese pendiente. |
ClearFields() | Vacía el contenido de todos los campos del registro actual. |
CommitUpdates() | Se indica a la base de datos que realice las actualizaciones que estaban en caché y se vacía el buffer de actualizaciones en caché. |
Close() | Cierra el conjunto de datos. |
Delete() | Elimina el registro actual. |
DisableControls() | Desactiva los controles de datos asociados al conjunto de datos (muy útil para evitar el parpadeo de los controles visuales). |
Edit() | Permite la edición del registro actual. |
EnableControls() | Activa los controles de datos asociados al conjunto de datos. |
FetchAll() | Obtiene todos los registros desde la posición actual del cursor hasta el final del conjunto de datos y los almacena localmente. |
FieldByName() | Devuelve un campo TField dado su nombre. |
First() | Mueve el cursor al primer registro. |
GetFieldNames() | Recupera la lista con los nombres de los campos del conjunto de datos. |
Insert() | Inserta un registro en blanco y pone el conjunto de datos en modo de edición. |
InsertRecord() | Inserta un registro en el conjunto de datos con los datos que se le indiquen y los envía con Post(). |
Last() | Sitúa el cursor en el último registro. |
Locate() | Búsqueda de un registro en particular. |
Lookup() | Localiza un registro por el medio más rápido posible y devuelve el dato contenido en el mismo (se usan índices si es posible). |
MoveBy() | Mueve el cursor un número determinado de filas. |
Next() | Mueve el cursor al siguiente registro. |
Open() | Abre el conjunto de datos. |
Post() | Escribe los datos modificados de un registro en el conjunto de datos (los envía a la base de datos o al buffer de actualizaciones en caché). |
Prior() | Mueve el cursor al registro anterior. |
Refresh() | Actualiza el contenido del registro actual leyéndolo de la base de datos. |
RevertRecord() | Cuando se utiliza la caché, este método ignora los cambios hechos previamente que todavía no han sido enviados a la base de datos. |
SetFields() | Establece los valores para todos los campos de un registro. |
UpdateStatus() | Devuelve el estado actual cuando las actualizaciones en caché se activan. |
Evento | Descripción (¿cuándo se genera?) |
---|---|
AfterCancel | Después de cancelar las modificaciones. |
AfterClose | Cuando se cierra un conjunto de datos |
AfterDelete | Después de que un registro se haya eliminado. |
AfterEdit | Después de que se ha modificado un registro. |
AfterInsert | Después de insertar un registro. |
AfterOpen | Después de abrir un conjunto de datos. |
AfterPost | Después de enviar los cambios de un registro. |
BeforeCancel | Antes de que se cancelen los cambios. |
BeforeClose | Antes de que se cierre un conjunto de datos. |
BeforeDelete | Antes de eliminar un registro. |
BeforeEdit | Antes de entrar en modo edición. |
BeforeInsert | Antes de que se inserte un registro. |
BeforeOpen | Antes de abrir el conjunto de datos. |
BeforePost | Antes de enviar las modificaciones. |
OnDeleteError | Cuando ocurre algún error al eliminar una tupla. |
OnEditError | Cuando ocurre algún error al editar una tupla. |
OnNewRecord | Siempre que se añade un nuevo registro. |
OnPostError | Cuando ocurre un error al enviar los cambios. |
OnUpdateError | Cuando ocurre un error al actualizar los datos. |
OnUpdateRecord | Cuando se actualiza el registro en la BD. |
Introducción de datos |
---|
void __fastcall TDataModuleXXX::TableNewRecord(TDataSet *DataSet) { DataSet->FieldValues["Date"] = Date(); } |
Validaciones a nivel de registros |
---|
void __fastcall TDataModulePersonal::tbEmpleadosBeforePost(TDataSet *DataSet) { if (Date() - tbEmpleadosHireDate->Value < 365 && tbEmpleadosSalary->Value > TopeSalarial) DatabaseError("¡Este es un enchufado!", 0); } |
Eliminación en cascada |
---|
void __fastcall TDataModulePedidos::tbPedidosBeforeDelete(TDataSet *DataSet) { tbLineas->First(); if (! tbLineas->Eof) if (MessageDlg("¿Eliminar detalles?",mtConfirmation, TMsgDlgButtons()<<mbYes<<mbNo, 0)==mrYes) { do { tbLineas->Delete(); } while (! tbLineas->Eof); } else { Abort(); } } |
Gestión de errores |
---|
Posible solución ante un error de bloqueo no concedido |
void __fastcall TDataModuleXXX::TableEditError (TDataSet *DataSet, EDatabaseError *E, TDataAction &Action) { // Consultar al usuario if ( MessageDlg ( E->Message, mtWarning, TMsgDlgButton() << mbRetry << mbAbort, 0) == mrRetry ) { // Esperar entre 1 y 2 segundos antes de reintentar Sleep(1000 + random(1000)); Action = daRetry; } else { // Abortar Action = daAbort; } } |
Códigos de error BDE |
void __fastcall TDataModuleXXX::TablePostError (TDataSet *TDataSet, EDatabaseError *E, TDataAction &Action) { AnsiString S; EDBEngineError *Err = dynamic_cast<EDBEngineError*>(E); if (Err) { for (int i = 0; i < Err->ErrorCount; i++) { if (i > 0) AppendStr(S, '\n'); TDBError *E = Err->Errors[i]; AppendStr(S, Format( "%.4x (%d): %s", ARRAYOFCONST((E->ErrorCode, E->NativeError,E->Message)))); } DatabaseError(S, 0); } } |
Mensajes de error personalizados |
int GetBDEError(EDatabaseError *E) { EDBEngineError *Err = dynamic_cast<EDBEngineError*>(E); if (Err) for (int I = 0; I < Err->ErrorCount; I++) { TDBError *dbe = Err->Errors[I]; if (dbe->NativeError == 0) return dbe->ErrorCode; } return -1; } // Relaciones maestro/detalle void __fastcall TDataModulePedidos::tbPedidosDeleteError (TDataSet *TDataSet, EDatabaseError *E, TDataAction &Action) { if (GetBDEError(E) == DBIERR_DETAILRECORDSEXIST) if ( MessageDlg( "¿Eliminar también las líneas de detalles?", mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0) == mrYes) { tbLineas->First(); while (! tbLineas->Eof) tbLineas->Delete(); // Reintentar el borrado en la tabla de pedidos Action = daRetry; } else // Fallar sin mostrar otro mensaje Action = daAbort; } // Evento OnPostError para cualquier tabla void __fastcall TDataModuleXXX::PostError (TDataSet *DataSet, EDatabaseError *E, TDataAction &Action) { TTable *T = static_cast<TTable*>(DataSet); switch (GetBDEError(E)) { case DBIERR_KEYVIOL: DatabaseErrorFmt("Clave repetida en la tabla %s", ARRAYOFCONST((T->TableName)), 0); break; case DBIERR_FOREIGNKEYERR: DatabaseErrorFmt("Error en clave externa. Tabla: %s", ARRAYOFCONST((T->TableName)), 0); break; } } |