2009-05-11 10 views
9

Tengo el siguiente código en un proyecto en el que estoy trabajando.¿Cuánto tiempo un marcador TDataset sigue siendo válido?

procedure TForm.EditBtnClick(Sender:TObject); 
begin 
    // Mark is form variable. It's private 
    Mark = cdsMain.GetBookmark; 
    // blabalbal 
    . 
    . 
    . 
end; 

procedure TForm.OkBtnClick(Sender:TObject); 
var 
    mistakes: Integer; 
begin 
    //Validation stuff and transaction control 
    //removed to not clutter the code 
    If cdsMain.ChangeCount <> 0 then 
    mistakes := cdsMain.AppyUpdates(-1); 
    cdsMain.Refresh; 
    try 
    cdsMain.GotoBookmark(Mark); 
    // Yes, I know I would have to call FreeBookmark 
    // but I'm just reproducing 
    except 
    cdsMain.First; 
    end; 
end; 

En lo personal, yo no uso de marcadores mucho - excepto para cambiar la posición de un conjunto de datos donde sólo moví la posición del cursor (para crear un perfil, llenar una lista de cadenas, etc.). Si yo Refresh, actualizo (especialmente cuando un filtro puede hacer que el registro sea invisible), reajuste (Close/Open) o cualquier operación que modifique los datos en el conjunto de datos, no uso marcadores. Prefiero Locate en la clave principal (usando un TClientDataset, por supuesto) o volver a consultar los parámetros.

¿Hasta cuándo es válido un marcador? Hasta un Refresh? Hasta que se haga un Close/Open para volver a buscar los datos? ¿Dónde termina la zona segura?

Considere la posibilidad en la respuesta que estoy usando TClientDataset con un TSQLQuery (DbExpress).

Respuesta

5

Al igual que c0rwin y skamradt ya mencionamos: el comportamiento del marcador depende del descendiente TDataSet que utilice.

En general, los marcadores de ser válidos durante:

  1. de apertura/cierre
  2. de actualización (en conjuntos de datos que lo soporten)
  3. cambios de datos (a veces sólo supresiones)

que conozco 1. y 2. pueden invalidar tus marcadores en TClientDataSets. Estoy casi seguro de que para TClientDataSets no importa qué proveedor subyacente se utiliza (TSQLQuery, TIBQuery, etc.).

La única manera de asegurarse de qué funciona y qué no es testeándolo. Lo que significa que tiene toda la razón al no usarlos: los marcadores tienen una posibilidad intrínseca de no ser confiable.

Para estar en el lado seguro, siempre llame a BookmarkValid antes de ir a un marcador.

+5

Después de algunas experimentaciones, incluso BookmarkValid no es confiable. Ocurre cuando tiene un filtro activado en el conjunto de datos: devuelve verdadero incluso si el registro no coincide con la condición del filtro. El resultado final es lanzar una excepción. –

1

TDataSet implementa métodos de marcadores virtuales. Si bien estos métodos aseguran que cualquier objeto de conjunto de datos derivado de TDataSet devuelve un valor si se llama a un método de marcador, los valores de retorno son meramente valores predeterminados que no hacen un seguimiento de la ubicación actual. Descendientes de TDataSet, tales como TBDEDataSet, reimplementar los métodos de marcadores para devolver valores significativos como se describe en la siguiente lista:

  • BookmarkValid, para determinar si un marcador especificado está en uso.
  • CompareBookmarks, para probar dos marcadores para ver si son iguales.
  • GetBookmark, para asignar un marcador a su posición actual en el conjunto de datos.
  • GotoBookmark, para regresar a un marcador previamente creado por GetBookmark
  • FreeBookmark, para liberar un marcador asignado con anterioridad por GetBookmark.

obtenerlo de here

+0

Gracias. Voy a reformular la pregunta, entonces. –

+0

Lamentablemente, no recuerdo la respuesta a esta pregunta, ya que dejé la programación de Delphi hace mucho tiempo. Mi intuición me dice que debería ser válida hasta que DataSet esté abierto, pero podría pensar en una implementación en la que podría ser útil incluso después de abrirla/cerrarla. También tiendo a estar de acuerdo con la respuesta a continuación, ya que definitivamente podría depender del vendedor. –

4

Personalmente, rara vez uso de marcadores. En su lugar, utilizo el id del registro que estoy viendo y realizo una búsqueda en él una vez que se completa la actualización. Si necesito iterar sobre todos los registros en el conjunto, lo hago usando un clon del tClientDataset (que obtiene su propio cursor).

Tengo entendido que la implementación del marcador depende del vendedor del tDataset descendiente y puede variar entre implementaciones. En mi conjunto de datos muy simple (tBinData), implementé marcadores como el número de registro físico, por lo que se mantendría entre las actualizaciones, siempre que no se eliminara el registro. No puedo decir esto en todas las implementaciones.

Cuestiones relacionadas