2008-12-05 28 views
6

No soy un programador de Delphi, pero tengo una aplicación antigua de Delphi 7 que necesito corregir y está usando ADO.¿Cómo evitar que Delphi ADO cargue toda la tabla en la memoria?

La tabla de la base de datos (MS Accesss) contiene +100,000 filas y cuando configuro el ADOTableable.Active = true, comienza a cargar toda la tabla en la memoria RAM y eso requiere mucha memoria y tiempo.

¿Cómo puedo evitar que ADO cargue toda la tabla? Traté de configurar los MaxRecords pero no ayuda.

Básicamente todo lo que hacemos es att inicio del programa:

// Connect to database 
DataModule.MyADOConnection.Connected:=true; 

DataModule.MeasurementsADOTable.MaxRecords:=1; 

// Open datatables 
DataModule.MeasurementsADOTable.Active:=true;     

Después de ajustar Activo = true que empieza a cargar las mediciones completas en la RAM y se necesita tiempo!

Estamos utilizando el proveedor MSDASQL.1. Tal vez no es compatible con la propiedad MaxRecords?

¿Cómo agrego alguna consulta de limitación en este objeto de datos para solo "cargar TOP 1 * desde las mediciones"?

Respuesta

10

Puede usar TADOQuery para limitar el conjunto de resultados con una consulta sql. O puede usar TADOTable y establecer el CursorLocation en un cursor del lado del servidor para evitar que el cliente cargue el conjunto de resultados completo en la memoria.

0
  1. En el módulo de datos donde "MeasurementsADOTable" reside en la actualidad, la caída de un TADOQuery y el nombre "MeasurementsADOQuery"
  2. Establecer la propiedad de conexión de MeasurementsADOQuery a MyADOConnection (suponiendo que este es el caso con base en el pequeño fragmento de código proporcionado.)
  3. también estoy suponiendo que se está mostrando una rejilla o de otra manera utilizar una fuente de datos - de cambio de propiedad "conjunto de datos" del componente de origen de datos de MeasurementsADOTable a MeasurementsADOQuery
  4. Editar la consulta real para ser ejecutado mediante el establecimiento de la propiedad SQL de MeasurementsADOQuery . (En tiempo de ejecución antes de la apertura: Measurements.SQL.Text: = 'select * 10 a partir de mediciones orden superior, por cualquier')
  5. Analizar/cambiar todas las referencias en código de MeasurementsADOTable a MeasurementsADOQuery
5

Se podría utilizar ese ADOTable con un cursor Server OpenForwardOnly y un TCLientDataset con PacketRecords establecido en un valor distinto de cero. Funcionó maravillosamente cuando tuve que escribir una aplicación para extraer datos de MSSQL a Oracle de forma personalizada con tablas con millones de registros.

EDITAR -> Sería algo en las líneas de esto:

procedure ConfigCDSFromAdoQuery(p_ADOQ: TADOQuery; p_CDS: TClientDataset; p_Prov: TDatasetProvider); 
begin 
    If p_ADOQ.Active then p_ADOQ.Close; 
    p_ADOQ.CursorLocation := clServer; 
    p_ADOQ.CursorType := ctOpenForwardOnly; 
    p_Prov.Dataset := p_ADOQ; 
    p_CDS.SetProvider(p_Prov); 
    p_CDS.PacketRecords := 100; 
    p_CDS.Open; 
end ; 

que he hecho todo esto por el código, pero la mayoría de que se puede hacer en tiempo de diseño.

+0

cómo conecto el TClientDataSet con mi MSACCESS? ¿Tienes algún código de muestra que puedas compartir? – Vlad

+1

@Vlad: El proceso es siempre el mismo: conecte TClientDataset (CDS) con un TDatasetProvider (DSP), después de ese punto la propiedad DSP.DataSet de propiedad a la ADOQuery está trayendo los datos. En la sección Delphi en About.com puedes encontrar miles de ejemplos y también en el docwiki de embarcadero. –

+0

Gracias, intentaré hacer un proyecto de muestra, pero aún una demostración con el "Servidor (ubicación del cursor?) El cursor OpenForwardOnly y un TCLientDataset con PacketRecords establecido en un valor distinto de cero" sería genial. ;) – Vlad

-1

He encontrado que ADO + Access w/Delphi es extremadamente lento, para muchas cosas (las lecturas de tablas grandes como las que describes, pero también las inserciones, etc.). Mi respuesta fue "Salir usando ADO y Access en total".

Nunca entendí por qué funcionaba tan mal, especialmente cuando las tecnologías anteriores parecían no funcionar.

1

Este artículo es específico de BDE, pero se aplica a ADO o a la mayoría de las bibliotecas de acceso a datos de clientes.

http://dn.codegear.com/article/28160

yo recomendaría usar TADODataSet (que es "más cerca" de la capa de ADO que TADOQuery) y seleccionando sólo los datos que el cliente necesite, proporcionando un formulario de búsqueda personalizada (rango de fechas, lista de elementos específicos, etc.)

Buena suerte

0

no haga que el activo ADOTable en el arranque y convertirlo después también es una manera, pero todavía no es realmente va a ayudar .... utilice un adodataset y poblar que más bien como sea necesario durante el tiempo de ejecución con su conexión texto. Solo se recuperarán los datos relevantes, lo que lo hará mucho más rápido.

0

uso adoquery Si usted no necesita ninguna fila y sólo desea insertar nuevo comando use la fila de SQL como esto 'select * from myTable donde id = -1' Desde Id es autonumber ninguna fila volverán. o 'select * from myTable where 1 = -1' Pero creo que no es una buena forma para Insering de datos. Usar adocommand es mucho mejor.

si quieres filas X 'seleccione la parte superior de X * myTable'

+0

seguro con la prevención de cargar toda la tabla en la memoria !!! usando adoquery en lugar de adotable, con una condición de condición falsa

Cuestiones relacionadas