Necesito mejora la velocidad al obtener un cursor en ADS.
En la ayuda de ADVANTAGE DATABASE SERVER se tiene la siguiente secuencia de instrucciones:
- Code: Select all Expand view RUN
DoSQL( void )
AdsCreateSQLStatement( hConnect, &hSQL ); //Prepara el AREA
AdsStmtSetTableType( hSQL, ADS_ADT );
AdsStmtSetTableRights( hSQL, ADS_IGNORERIGHTS ); //Establece algunas propiedades
AdsStmtSetTableLockType( hSQL, ADS_PROPRIETARY_LOCKING );
AdsStmtSetTableCharType( hSQL, ADS_ANSI );
AdsStmtConstrainUpdates( hSQL, ADS_CONSTRAIN );
AdsStmtSetTableReadOnly( hSQL, ADS_CURSOR_READWRITE );
AdsPrepareSQL( hSQL, "SELECT * FROM plane WHERE arrival = :ArrivalParam" ); //Prepara el SQL
AdsSetTimeStamp( hStatement, "ArrivalParam", "04/18/1999 7:00 AM",
AdsExecuteSQL( hSQL, &hCursor ); //CREA el cursor
AdsCloseTable( hCursor ); //CIERRA el cursor
AdsClearSQLParams( hSQL );
AdsPrepareSQL( hSQL, "SELECT * FROM plane WHERE arrival = ?" ); //CREA otro cursor, sin cerrar el AREA
AdsSetTimeStamp( hStatement, ADSFIELD( 1 ), "04/18/1999 7:00 AM", //CIERRA el cursor
AdsExecuteSQL( hSQL, &hCursor );
AdsCloseTable( hCursor );
AdsClearSQLParams( hSQL );
AdsExecuteSQLDirect( hSQL, "Select lastname from Demo10", &hCursor ); //CREA otro cursor, sin cerrar el AREA
AdsGotoTop( hCursor );
AdsSkip( hCursor, 1 );
AdsGetString( hCursor, "Lastname", aucFieldVal, &ulLength, ADS_NONE );
AdsSetString( hCursor, "Lastname", "Johnson", strlen( "Johnson" ) );
AdsCloseTable( hCursor ); //CIERRA el cursor
AdsCloseSQLStatement ( hSQL ); //Cierra el area
AdsDisconnect( hConnect ); //Cierra la CONEXION
Quiero hacer lo mismo en FWH/xharbour:
1. Preparar AREA
2. Abrir cursor
3. Cerrar cursor
.
.
100. Abrir cursor
101. Cerrar cursor
102. Cerrar AREA
Tengo la siguiente secuencia de instrucciones que funcionan con algo similar
- Code: Select all Expand view RUN
AdsCreateSqlStatement( "Empleado", ADS_CDX, nConnection ) //Prepara el AREA
ADSExecuteSQLDirect("SELECT TOP 0 * FROM Empleados;") //CREA el cursor
.
.
DBSelectArea( "Empleado" ) //Selecciono el AREA
DbCloseArea() //Necesariamente TENGO que cerrar el AREA
//que ejecuta AdsCloseSQLStatement() y otras cosas mas
AdsCreateSqlStatement( "Empleado", ADS_CDX, nConnection ) //Nuevamente Prepara el AREA
ADSExecuteSQLDirect("SELECT TOP 1 * FROM Empleados WHERE Upper([NAME])='Juan';") //Nuevamente CREA el cursor
Msginfo(Empleado->NOMBRE) //Muestra el nombre
.
.
DbCloseArea() //Cierra el area que ejecuta AdsCloseSQLStatement() y otras cosas mas
Lo cambie por esto:
- Code: Select all Expand view RUN
AdsCreateSqlStatement( "Empleado", ADS_CDX, nConnection ) //Prepara el AREA
ADSExecuteSQLDirect("SELECT TOP 0 * FROM Empleados;") //CREA el cursor
.
.
DBSelectArea( "Empleado" ) //Selecciono el AREA
//esto SOLO deberia cerrar el CURSOR
AdsCloseCursor() //ESTA ES LA NUEVA FUNCION implementada en adsfunc.c
//esto seria como recargar el CURSOR
//pero provoca error, el programa falla
//no muestra ningun mensaje
//Solo Windows indica que el progrma fallo
ADSExecuteSQLDirect("SELECT TOP 1 * FROM Empleados WHERE Upper([NAME])='Juan';")
Msginfo(Empleado->NOMBRE) //Muestra el nombre
.
.
DbCloseArea() //Cierra el area que ejecuta AdsCloseSQLStatement() y otras cosas mas
Previamente añadi la funcion AdsCloseCursor() a adsfunc.c. Compile y cree la LIB en forma correcta.
- Code: Select all Expand view RUN
HB_FUNC( ADSCLOSECURSOR )
{
ADSAREAP pArea = hb_adsGetWorkAreaPointer();
if( /* hb_ads_hConnect && */ pArea && pArea->hStatement )
{
if( pArea->hTable )
{
UNSIGNED32 ulRetVal = AdsCloseTable( pArea->hTable );
if( ulRetVal == AE_SUCCESS )
{
pArea->hOrdCurrent = 0;
pArea->hTable = 0;
/* Free field offset array */
/*if( pArea->pFieldOffset )
{
hb_xfree( pArea->pFieldOffset );
pArea->pFieldOffset = NULL;
}*/
/* Free buffer */
if( pArea->pRecord )
{
hb_xfree( pArea->pRecord );
pArea->pRecord = NULL;
}
/* Free all filenames */
if( pArea->szDataFileName )
{
hb_xfree( pArea->szDataFileName );
pArea->szDataFileName = NULL;
}
hb_retl( TRUE );
}
else
{
HB_TRACE(HB_TR_DEBUG, ("adsCloseTable() error"));
hb_retl( FALSE );
}
}
else
hb_retl( FALSE );
}
else
hb_retl( FALSE );
}
La funcion AdsCloseCursor() devuelve .T., lo cual indica que cerro bien el cursor,
pero cuando ejecuto la siguiente instruccion ADSExecuteSQLDirect() el programa deja de funcionar
Que mas habria que añadir a la funcion AdsCloseCursor() para que ADSExecuteSQLDirect() se ejecute en forma correcta?
De antemano GRACIAS POR LA AYUDA.
Rolando
Cochabamba, Bolivia