Está en la página 1de 4

Una aplicación VFP/SQL SERVER de principio a fin - Parte V

La quinta parte de este artículo está dedicada al estudio de ADO Tópico: Visual FoxPro - SQL Server Nível:
dentro de Visual FoxPro, por eso las funciones que voy a presentar
ahora son una continuación de las presentadas en la parte IV. Son funciones de vital importancia para el futuro del
proyecto, ya que una falla en este punto comprometerá a todo el sistema.

Cuando inicié el proyecto "Una aplicación VFP/SQL SERVER de principio a fin" el Visual FoxPro8.8 aún no habia
sido lanzado oficialmente (estaba la versión beta), por eso todas las funciones que se presentan fueron
Frederico desarrolladas, probadas y están siendo utilizadas en la versión 7.0.
Tomazetti
Sabemos que en la versión 8.0 existen funciones ya listas que facilitan mucho mas la vida del desarrollador que pretende trabajar con
Visual FoxPro y SQL SERVER.

Ejecutando comandos Transact/SQL

La función siguiente ejecuta una sentencia SQL en la base de datos

El principal detalle está en los parámetros recibidos por la función. El primero "pStringSql" es el string que será ejecutado, algo como :
"Select * from clientes"

El segundo parámetro (pCursorLocation) indica en que lado será creado el cursos, si en el lado cliente o en el del servidor, eso tiene
una relevancia muy grande en el desempeño del sistema y en el tráfico que causará en la red.

No podemos decir que el cursor del lado del cliente es mejor que del lado del servidor o viceversa, porque eso depende de como esté
la estructura de su sistema y si el usuario posee un servidor sobrecargado o si las máquinas clientes poseen procesadores rápidos o
lentos, o sea, factores externos influenciarán este tipo de decisiones.

En mi caso utilizo el cursor del lado "cliente" cuando se que el retorno de datos no será muy grande y del lado del servidor cuando
fuera una cantidad mayor o cuando estuviera ejecutando un INSERT, UPDATE o DELETE en una tabla.

El tercer parámetro (pCursorType) indica el tipo de apertura del cursor y posee 4 opciones (Valores de 0 a 3), el mas utilizado es el
valor cero (Default) definiendo la apertura del cursor como "forward only", si utilizan la opción 3, por ejemplo, solo podrá leer datos.
Aparentemente la opción 2 (adOpenDynamic) sería la mejor pero consume procesamiento y nosotros precisamos apenas leer
sequencialmente los datos.

El cuarto parámetro (pLockTyp) indica el tipo de bloqueo que ADO ejecuta en el registro de una tabla de la base de datos. Este
proceso es prácticamente el mismo utilizado nativamente en tablas de Visual FoxPro.

Normalmente utilizo el tipo de bloqueo default (1 - adLockReadOnly) por ser más seguro que los demás.

*************************************************************
* Procedure: Executar
* Objetivo: Ejecutar una sentencia SQL en la base de datos via ADO
* Parámetros: pStringSQL - string que será ejecutada en la base
* pCursorLocation - Local al cursor
* 2 = adUseServer (Default)
* 3 = adUseClient
* pCursorType - Tipo de apertura del cursor
* 0 = adOpenForwardOnly (Default)
* 1 = adOpenKeyset
* 2 = adOpenDynamic
* 3 = adOpenStatic
* pLocktype - Tipo de Bloqueo
* 1 = adLockReadOnly (Default)
* 2 = adLockPessimistic
* 3 = adLockOptimistic
* 4 = adLockBatchOptimistic
* Retorno: True o False
*************************************************************

Procedure Executar (pStringSql As String,;


pCursorLocation As Integer,;
pCursorType As Integer,;
pLocktype As Integer) As Boolean
Esta parte de la función verifica el tipo de datos y, en caso de que algún parámetro no haya sido informado, será asumido el valor
default.

With This
If Vartype(pStringSql)<> "C"
Return .F.
Endif
If Vartype(.loConn) # "O"
*-- Si no hubiera conexión establece la conexión
If !.Conectar()
Return .F.
Endif
Endif

*-- Tipo de Localización de RS


If Vartype(pCursorLocation) <> "N"
pCursorLocation = 2
Else
If !(pCursorLocation >= 2 And pCursorLocation <= 3)
pCursorLocation = 2
Endif
Endif

*-- Tipo de Cursor


If Vartype(pCursorType) <> "N"
pCursorType = 0
Else
If !(pCursorType >= 0 And pCursorType <= 3)
pCursorType = 0
Endif
Endif

*-- Tipo de Bloqueo


If Vartype(pLocktype) <> "N"
pLocktype = 1
Else
If !(pLocktype >= 1 And pLocktype <= 4)
pLocktype = 1
Endif
Endif
If Vartype(.lors) # "O"
*-- Se Crea el objeto RS si no existe
.lors = Createobject("adodb.recordset")
Else
If .lors.State = 1
.lors.Close
Endif
Endif

En este punto los parámetros alimentan la conexión ADO y se crea el objeto con los datos resultantes de la búsqueda.

With .lors
.CursorLocation = pCursorLocation
.CursorType = pCursorType
.LockType = pLocktype
.Open(pStringSql,This.loConn)
Endwith
ENDWITH

Aquí tenemos un tratamiento de error, en caso de que exista algún problema con la conexión o con el string a ser ejecutado.

If This.loConn.Errors.Count>0
This.nNativeError = This.loConn.Errors.Item(0).NativeError
This.cMensError = "Numero do Error: "+;
Transform(This.loConn.Errors.Item(0).NativeError) + Chr(13) +;
"Descripción Error: "+This.loConn.Errors.Item(0).Description + Chr(13) +;
"Origen del Error: "+This.loConn.Errors.Item(0).Source
Endif
Return Iif(This.loConn.Errors.Count>0,.F.,.T.)
Endproc

Grabando un recordset
Esta pequeña función graba un RecordSet en un archivo XML o en una estructura ADO, vamos a utilizar 100 % archivo XML, una
estructura ADO fue utilizada sólo para fines de compatibilidad.

*************************************************************
* Procedure: SalvarRS
* Objetivo: Grabar un RecordSet en un archivo XML o una estructura ADO
* Parámetros: pTipoDado: 1 - graba en XML / 0 - Graba en formato ADO
* pNome - nombre del archivo Temporário
*************************************************************
Procedure SalvarRS (pTipoADO As Integer,pNome As String) As Boolean
Local llOK
If Vartype(pNome) <> "C"
pNome = "temp\" + "ADO.TXT"
Endif
If File(pNome)
Delete File &pNome
Endif
With This
If Vartype(.lors) = "O"
If .lors.State = 1
.lors.Save (pNome,pTipoADO)
llOK = .T.
Endif
Endif
Endwith
Return llOK
Endproc

Creando un cursor local

Para crear un cursor local de Visual FoxPro con los datos que recibiremos del SQL SERVER precisamos utilizar XML. Vea la función
siguiente, que utiliza las dos funciones ya tratadas antes.

La función recibe un string (pSql), un nombre para un archivo temporario - cursor local - (pArqTmp), un tipo de cursor (pTipoCursor) y
la información de si este cursor recibirá un registro en blanco después de ser creado (muy útil para el ingreso de datos a través de
grids).

Aquí vale destacar que es necesario poseer el service pack 1 de Visual FoxPro7 (disponible para el download en el sitio de Microsoft),
ya que este service pack corrige un problema que ocurría en el comando XMLTOCURSOR.

*************************************************************
* Procedure: CriaCursor
* Objetivo: Crear un cursor local de VFP a través de RecordSet ADO
* Parâmetros: pSql = Comando SQL a ser ejecutado
* pArqTMP = Nombre del Archivo TMP generado
* pTipoCursor = Flag que identifica el tipo de cursor generado
* (.T. = 512 , .F. = 512 + 8192)
* pInsereRegistro = Insertar un registro en blanco después de crear el cursor
*************************************************************
parameters pSql,;
pArqTMP,;
pTipoCursor,;
pInsereRegistro
Local llRetorno
Local lcXML
If _Screen.omanipuladados.Executar(pSql)
lcXML = "temp\"+Sys(2015)+".xml"
If _Screen.omanipuladados.SalvarRS(1,lcXML)
Xmltocursor(lcXML,pArqTMP,Iif(!pTipoCursor,512 + 8192,512))
Delete File &lcXML
If !pInsereRegistro
If Reccount() = 0
Append Blank
Endif
Endif
llRetorno = .T.
Endif
Else
=RotinaDeErro (_Screen.omanipuladados.cMensError + Chr(13)+Chr(13) ;
+"Falla la llamada del view!" ,'', _Screen.omanipuladados.nNativeError, .T.)
Endif
Return llRetorno
Frederico Tomazetti trabaja en desarrollo de sistemas hace 15 años utilizando Fox desde su primera versión, pasando por FoxProDOS, Unix, Windows
y hoy en dia el Visual FoxPro, actualmente desarrolla sistemas en Visual FoxPro versión 7.0 utilizando las bases SQL SERVER y ORACLE, fue creador
del grupo FoxMinas y puede ser contactado en el e-mail: ftomazetti@yahoo.com.br

También podría gustarte