Como ejecutar un script SQL desde VFP (VFP)
De VesWiki, la enciclopedia libre.
|
Por: VictorEspina
[editar] IntroducciónCuando desarrollamos aplicaciones que utilizan a SQL Server como almacén de datos, frecuentemente nos encontramos con el problema de como crear la base de datos y como actualizar posteriormente. Normalmente, estas labores se logran a través de scripts SQL. los cuales son archivos de texto que contienen una o mas sentencias SQL (bien sea DML o DDL), separadas por el comando GO, y que se ejecutan sobre el servidor. Tradicionalmente, estos scripts se ejecutan usando:
A primera vista el problema parece sencillo:
El problema es que SQLEXEC() no esta diseñado para ejecutar VARIAS instrucciones, sino solo una. [editar] La soluciónLa solución es aplicar un "parsing" al script, utilizando el comando GO como separador de instrucciones y enviar cada instrucción por separado usando el comando SQLEXEC(). El siguiente procedimiento CFRunSqlScript hace justamente eso. Su uso es muy sencillo:
LOCAL cScript
cScript = FILETOSTR("myscript.sql")
TRY
CFRunSqlScript(nConn,cScript)
CATCH TO ex
MESSAGEBOX(ex.Message)
ENDTRY
donde cScript contiene el texto del script SQL a ejecutar y nConn contiene el handle de la conexión con el servidor donde se desea ejecutar el script. Como es costumbre en estos casos, el uso de este código queda completamente bajo la responsabilidad del usuario y el autor (o sea, yo) no podrá ser encontrado responsable de ninguna perdida o daño causado por el uso de este fuente.
*******************************************************************
* CFRunSQLScript
* Funcion para ejecutar un script SQL en una conexion dada
*
* Parametros:
* pnConn : Handle de conexión ODBC
* pcScript: Texto del script a ejecutar, contentivo de una o mas
* instrucciones SQL separadas por el comando "GO"
*
* Autor: Victor Espina
* Fecha: Mayo 2007
********************************************************************
#DEFINE True .T.
#DEFINE False .F.
PROCEDURE sqlRunScript(pnConn,pcScript)
*
*--- Se carga el script en memoria divido en lineas
LOCAL ARRAY aScript[1]
LOCAL nScriptSize
nScriptSize = ALINES(aScript,pcScript + CHR(13) + CHR(10) + "GO")
*-- Se recorre el script. Se acumula en un buffer cada linea
* del script (que no sea comentario) hasta llegar a una
* linea en blanco o a un GO. En ese momento se enviar el
* contenido del buffer al servidor y se limpia
*
LOCAL cBuffer,nCommentDeep,i,cLine,lError,oEX,nResult,aOdbcError[1]
nCommentDeep = 0
cBuffer = ""
lError = False
FOR i = 1 TO nScriptSize
*
cLine = aScript[i]
*-- Si la linea empieza por "--", se descarta
IF LEFT(LTRIM(cLine),2) == "--"
LOOP
ENDIF
*-- Si la linea empieza por /* se marca el inicio de un bloque de comentario
IF LEFT(LTRIM(cLine),2) == "/*"
nCommentDeep = nCommentDeep + 1
LOOP
ENDIF
*-- Si la linea empieza por "*/" se marca el final de un bloque de comentarios
IF AT("*/",cLine)<>0
nCommentDeep = nCommentDeep - 1
LOOP
ENDIF
*-- Si esta activo un bloque de comentario, se pasa a la siguiente linea
IF nCommentDeep > 0
LOOP
ENDIF
*-- Si es una linea GO, se ejecuta el buffer
IF UPPER(ALLTRIM(cLine))=="GO"
*
IF NOT EMPTY(cBuffer)
nResult = SQLEXEC(pnConn,cBuffer)
IF nResult < 0
oEx = CREATEOBJECT("CFLastErrorException")
lError = True
ENDIF
DOEVENTS
ENDIF
cBuffer = ""
IF lError
EXIT
ENDIF
LOOP
*
ENDIF
IF lError
EXIT
ENDIF
*-- Se incluye la linea en el buffer
cBuffer = cBuffer + cLine + CRLF
*
ENDFOR
*-- Si ocurrio un error, se propaga al nivel superior
*
IF lError
THROW oEX
ENDIF
*
ENDPROC
*-- CFLastErrorException
* Excepcion con los datos del ultimo error ocurrido
*
DEFINE CLASS CFLastErrorException AS Exception
*
PROCEDURE Init
*
DODEFAULT()
LOCAL ARRAY aErrInfo[1]
AERROR(aErrInfo)
DO CASE
CASE INLIST(aErrInfo[1],1427,1429) && OLE Error
THIS.ErrorNo = aErrInfo[7]
THIS.Message = aErrInfo[3]
CASE aErrInfo[1] = 1526 && ODBC Error
THIS.ErrorNo = aErrInfo[5]
THIS.Message = aErrInfo[3]
OTHERWISE && VFP Error
THIS.ErrorNo = aErrInfo[1]
THIS.Message = aErrInfo[2]
ENDCASE
*
ENDPROC
*
ENDDEFINE
|
|
