FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Problema con SQL y/o ADS - SOLUCIONADO
Posts: 234
Joined: Tue Sep 01, 2009 07:55 AM

Problema con SQL y/o ADS - SOLUCIONADO

Posted: Thu Feb 24, 2011 03:56 PM
Hola:
Estoy intentado filtrar una tabla DBF/CDX con ADS, usando sentencias SQL, y aqui me viene lo curioso:
Code (fw): Select all Collapse
    SELECT 0
    ADSCreateSQLStatement( "sql",2 , conection )
    ADSExecuteSQLDirect( "select * from expedien where inactivo = 'ACTIVO                        ' ORDER BY APELLIDO" )
    sql->(dbgotop())

esto me devuelve el error 5018 apuntando a sql->(dbgotop())
sinembargo
Code (fw): Select all Collapse
    SELECT 0
    ADSCreateSQLStatement( "sql",2 , conection )
    ADSExecuteSQLDirect( "select * from expedien where inactivo = 'ACTIVO                        ' " )
    sql->(dbgotop())

funciona perfecto, el SQL de ADS soporta la clausula "order", ¿que estoy haciendo mal para que me provoque ese error?
Muchas gracias y un saludo
José Luis
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM

Re: Problema con SQL y/o ADS

Posted: Thu Feb 24, 2011 06:44 PM
yo lo he usado sin problemas, te adjunto el codigo para que lo mires

Code (fw): Select all Collapse
PROCEDURE Clientes_Listar2()
   LOCAL cSql:=""
   LOCAL cAlias := Alias()

   /*al inicio de la instruccion sql se define un area vacia*/
   DBSelectArea(0)

   /*se define instruccion sql en una cadena de texto*/
   TEXT INTO cSql
      SELECT B.NOMBRE, A.NUMERO, A.FECHA, A.CODCLIE, A.TOTAL, A.TC, A.CREDITO, A.PAGADO, A.TOTAL/A.TC AS TOTALD ;
         FROM MSALIDAS AS A, CLIENTES AS B ;
         WHERE A.CODCLIE = B.CODIGO AND A.CREDITO=TRUE AND A.PAGADO<>TRUE
   ENDTEXT

   /*reemplaza comas por espacion vacios*/
   cSql := StrTran( cSql, ";", "" )

   /*crea instruccion sql y pasa los datos a tabla temporal*/
   ADSCreateSQLStatement( "REPTMP", 2 )
   IF ADSExecuteSQLDirect( cSql )

      DBSelectArea("REPTMP")

      REPTMP->( DBGoTop() )
      IF !REPTMP->( Eof() )

         /*lista resultado en tabla*/
         Clientes_Listar2R()

      ELSE

         /*no se encontro datos que cumpla condicion sql*/
         MsgInfo( "No se ha encontrado clientes con creditos pendiente!" )

      ENDIF

      /*cierra tabla de datos temporal*/
      REPTMP->( DBCloseArea() )

   ENDIF

   /*se selecciona area de datos anterior*/
   IF !Empty(cAlias)
      DBSelectArea(cAlias)
   ENDIF

   /*da foco al browse*/
   oBrw:SetFocus()

RETURN
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM

Re: Problema con SQL y/o ADS

Posted: Thu Feb 24, 2011 06:47 PM
otra funcion, aca uso una funcion llamada StrFormat, que esta en la misc de xharbour, me sirve para pasar parametros a la cadena sql

Code (fw): Select all Collapse
PROCEDURE Productos_MovimientosQuery()
   PRIVATE cErr
   PRIVATE cCodProd
   PRIVATE cSql_S, cSql_E
   PRIVATE lSql_S, lSql_E
   PRIVATE nCanS, nCanE
   PRIVATE nTotS, nTotE

   /*inicializa variables*/
   cCodProd := PROD->CODIGO
   lSql_S   := FALSE
   lSql_E   := FALSE

   /*inicializa acumulador*/
   nCanS:=0
   nTotS:=0
   nCanE:=0
   nTotE:=0

   /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
   /*ejecuta query a las salidas del productos*/
   DBSelectArea(0)
   TEXT INTO cSql_S
      SELECT MS.FECHA, MS.NUMERO, DS.CODPRO, DS.NOMPRO, DS.CANPRO, DS.PREVEN, DS.TOTAL ;
         FROM DSALIDAS AS DS, MSALIDAS AS MS ;
         WHERE DS.CODPRO = '%1' AND DS.NUMERO = MS.NUMERO
   ENDTEXT
   cSql_S := StrTran( cSql_S, ";","" )
   cSql_S := StrFormat( cSql_S, cCodProd )
   ADSCreateSQLStatement( "SQLS", 2 )
   IF ADSExecuteSQLDirect( cSql_S )
      lSql_S := TRUE
      DBSelectArea( "SQLS" )
      SUM CANPRO, TOTAL TO nCanS, nTotS
      SQLS->( DBGoTop() )
   ENDIF

   /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
   /*ejecuta query a las entradas del productos*/
   DBSelectArea(0)
   TEXT INTO cSql_E
      SELECT ME.FECHA, ME.NUMERO, DE.CODPRO, DE.NOMPRO, DE.CANPRO, DE.PREPRO, DE.PRETOT ;
         FROM DENTRADAS AS DE, MENTRADAS AS ME ;
         WHERE DE.CODPRO = '%1' AND DE.NUMERO = ME.NUMERO
   ENDTEXT
   cSql_E := StrTran( cSql_E, ";","" )
   cSql_E := StrFormat( cSql_E, cCodProd )
   ADSCreateSQLStatement( "SQLE", 2 )
   IF ADSExecuteSQLDirect( cSql_E )
      lSql_E := TRUE
      DBSelectArea( "SQLE" )
      SUM CANPRO, PRETOT TO nCanE, nTotE
      SQLE->( DBGoTop() )
   ENDIF

   /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

   IF lSql_S .and. lSql_E
      Productos_MovimientosBrowse()
   ENDIF

   /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
   /*cierra tablas temporales de query*/
   SQLS->( DBCloseArea() )
   SQLE->( DBCloseArea() )

RETURN
Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 211
Joined: Wed Jul 16, 2008 12:59 PM

Re: Problema con SQL y/o ADS

Posted: Fri Feb 25, 2011 01:00 AM
Jose Luis:

Yo me cree la siguiente funcion:

Code (fw): Select all Collapse
Function SQL_Ejecuta(cInstruccion, lCloseArea, nConnect, cAlias )
local lOk := .F.
local cLastErr:=""

   DEFAULT lCloseArea := .f.
   DEFAULT cAlias := "SQL"

   //si "cAlias" ya estuviese abierta, la cerramos; porque si la dejamos abierta se produce un error
   if(select(cAlias)>0,(cAlias)->(DBCloseArea()),NIL)

   AdsConnection( nConnect )

   DBSELECTAREA( nTailEmptyArea( ) )

   if ADSCreateSQLStatement(cAlias,2)// 1= DBFNTX 2 = DBFCDX 3=ADTADI
      if .NOT. (lOk := ADSExecuteSQLDirect(cInstruccion)) .OR. lCloseArea
         if ! lOk
        AdsGetLastError(@cLastErr)
            MsgStop( cLastErr + CRLF  + CRLF + ;
                 "at ADSExecuteSQLDirect " + CRLF + CRLF +;
             "with instruction:" + CRLF + cInstruccion, "SQL_Ejecuta(..)" )
         endif
         DBCloseArea()
      endif
   else
      MsgStop( "No se puede crear el area de trabajo para ADSExecuteSQLDirect(..)", "SQL_Ejecuta(..)" )
   endif

return lOK
//--------------------------//
STATIC function nTailEmptyArea( ) // Returns el primer area libre
   local n, nArea
   for n = 255 TO 1 STEP -1
      if Empty( Alias( n ) )
         nArea := n
     exit
      endif
   next
return nArea


y utilizo esta funcion para traducir una una variable en una instruccion SQL

Code (fw): Select all Collapse
//--------------------------//
FUNCTION Str2Sql( xVar)
   SWITCH ValType(xVar)
   CASE "N"
      RETURN " " + cValToChar(xVar) + " "
   //CASE "D"
   //   RETURN "'" + strtran(HB_ValToStr(xVar),"/","-") + "'"
   CASE "L"
      RETURN if(xVar," true "," false ")
   END
RETURN " '" + cValToChar(xVar) + "' "


Aca hay unos ejemplos de como lo uso:

Code (fw): Select all Collapse
IF SQL_Ejecuta( "SELECT SUM(total) Total FROM FTCOMPRA WHERE fecha >= " + Str2Sql( dFecha),,,"SQL_SUM" )
   SQL_SUM->(DBEval({||Msginfo(FIELD->FECHA)}))
   SQL_Ejecuta("INSERT INTO DCBTE (cuenta,fecha,debe,haber ) "+;
           "VALUES ("+Str2Sql(cCuenta)+","+;
                  Str2Sql(dFecha)+","+;
                  Str2Sql(SQL_SUM->Total)+","+;
                  Str2Sql(0)+");",.T. )

   SQL_SUM->(DBCloseArea())
ENDIF

SQL_Ejecuta("DELETE FROM PERIODO WHERE FechaF < "+Str2Sql( dIGestion )+";", .T. )

SQL_Ejecuta("EXECUTE PROCEDURE sp_PackTable('PERIODO')",.T.)


Espero que te sirva, y si tienes alguna mejora me cuentas...

Atentamente,

Rolando Salazar U.
SAURO SOFTWARE SRL.
Email: SauroSrl@entelnet.bo
MSN: SauroSrl@hotmail.com
Av. República # 2316
Cochabamba - Bolivia

No te olvides visitar la pagina de Sauro Srl. http://WWW.SAURO-SYS.COM
Descargá los programas y haz una prueba, y si te sirven ….. compra una licencia…
Posts: 234
Joined: Tue Sep 01, 2009 07:55 AM

Re: Problema con SQL y/o ADS

Posted: Fri Feb 25, 2011 07:04 AM

Muchas gracias a los dos por contestar, pero fijaros que el problema no debe ser la construcción y ejecución de la sentencia SQL, entre el primer código y el segundo, la única diferencia es que en el primero se añade "ORDER BY APELLIDO", esto provoca un erro en harbour 5018, y en advantage SQL un error 8026.
El segundo código funciona perfectamente y me devuelve un total de 200 registros.
Algo hago mal al poner el "ORDER BY" pero no acabo de entender que
Gracias y un saludo
José Luis

Posts: 234
Joined: Tue Sep 01, 2009 07:55 AM

Re: Problema con SQL y/o ADS - SOLUCIONADO

Posted: Fri Feb 25, 2011 07:55 AM

Hola:
El problema no radicaba en las sentencias SQL, por lo que he indagado, al añadir la clausula "ORDER BY", en el lado del servidor, se debe crear un fichero temporal y yo usaba para la conexión el path en el servidor, pero ese path estaba un nivel por encima del lugar en el que se creaba la "respuesta" por lo cual no podía devolverme resultados, modifiqué el path y todo resuelto.

En el adsserver.ini tenía este alias:
[ServerAliases]
Tablas = c:\TABLAS\datos

lo cambié por:
[ServerAliases]
Tablas = c:\TABLAS\datos

mi conexión era esta:
AdsConnect60("\Correo\TABLAS\gerencia.add",7,,,4,@conection)

y la cambié por esta:
AdsConnect60("\Correo\TABLAS\datos\gerencia.add",7,,,4,@conection)

y todo resuelto.
Muchas gracias y un saludo
José Luis

Continue the discussion