Página 1 de 1

Problemas con TMySQLDataSource.

Publicado: Dom Oct 07, 2007 5:30 pm
por Juan Jose Zamora San
Hola a todos,
Estoy teniendo problemas al utilizar TMySQLDataSource con estructuras
complejas como por ejemplo la siguiente:
WITH OBJECT oGastos1 := TSQLQuery():New( Self )
:oDataSource := AppData:oConeMySQl
:cSelect := "SELECT NOMBREGASTO, "
FOR n:= 1 TO LEN( aaNosGastos )
:cSelect += "SUM( IF( ANO = " + ALLTRIM( STR( aaNosGastos[ n
], 4, 0 ) ) + ;
", IMPORTE_GASTO, 0 ) ) AS ANO" + ALLTRIM( STR(
aaNosGastos[ n ], 4, 0 ) ) + ", "
NEXT
:cSelect += "SUM( IMPORTE_GASTO ) AS SUMAGASTO FROM ( "
:cSelect += "SELECT gastos.N_CONTRATO, gastos.N_GASTO,
YEAR(gastos.FECHA) AS Ano, " +;
"contrato.DESCRIPCION, Sum(gastos.IMPORTE) AS
IMPORTE_GASTO, contrato.NCLIENTE, " +;
"clientes.NOMBRE, conceptosgastos.DESCRIPCION AS
NOMBREGASTO " +;
"FROM gastos Inner Join contrato ON gastos.N_CONTRATO
= contrato.N_CONTRATO " +;
"Inner Join clientes ON contrato.NCLIENTE =
clientes.NCLIENTE " +;
"Inner Join conceptosgastos ON gastos.N_GASTO =
conceptosgastos.CODIGO " +;
"GROUP BY gastos.N_CONTRATO, gastos.N_GASTO, Ano,
contrato.NCLIENTE, clientes.NOMBRE " +;
"HAVING gastos.N_CONTRATO = '" + cContrato + "' "
+;
"ORDER BY contrato.NCLIENTE, gastos.N_CONTRATO,
conceptosgastos.DESCRIPCION " +;
" ) AS consulta1 GROUP BY NOMBREGASTO"
:lOpen := .T.
:Create()
END WITH
Cuando pasa por el :Create da el siguiente error:
***************************** Registro de errores
*****************************
Fecha: 07-10-2007
Hora: 17:15:16
Memoria libre: 633912
Area actual: 1
------------------------- Información del compilador
--------------------------
Versión Xailer: Xailer 1.6.6 Version 1.6
Compilador: xHarbour build 0.99.61 Intl. (SimpLex) PCode Version: 7
Compilador C/C++: Borland C++ 5.5.1
Plataforma: Windows XP Professional 5.01.2600 Service Pack 2
----------------------- Información detallada del error
-----------------------
Subsistema: MySQL
Código de error: -1
Estado: .T.
Descripción: You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near '(' at line 1
Operación: TMYSQLRECORDS:QUERYALL
Argumentos: [ 1] = Tipo: C Valor: SHOW INDEX FROM (
Fichero:
Código error SO: 0
Pila de llamadas:
TMYSQLRECORDS:QUERYALL (185)
TMYSQLRECORDS:OPEN (149)
TSQLQUERY:OPEN (308)
TDATASET:CREATE (222)
TSQLQUERY:CREATE (39)
TFORM1:BUTTON1CLICK (295)
TBUTTON:ONCLICK (0)
TBUTTON:CLICK (99)
(b)XCONTROL:XCONTROL (140)
TBUTTON:COMMAND (0)
TSCROLLINGWINCONTROL:WMCOMMAND (253)
TFORM1:WMCOMMAND (885)
RUNFORM (0)
TAPPLICATION:RUN (209)
MAIN (43)
Esta sentecia traducida al castellano es la siguiente:
SELECT NOMBREGASTO,
SUM( IF( ANO = 2005, IMPORTE_GASTO, 0 ) ) AS ANO2005 ,
SUM( IF( ANO = 2006, IMPORTE_GASTO, 0 ) ) AS ANO2006 ,
SUM( IF( ANO = 2007, IMPORTE_GASTO, 0 ) ) AS ANO2007 ,
SUM( IMPORTE_GASTO ) AS SUMAGASTO
FROM (
SELECT gastos.N_CONTRATO, gastos.N_GASTO, YEAR( gastos.FECHA )
AS Ano,
contrato.DESCRIPCION, Sum(gastos.IMPORTE) AS IMPORTE_GASTO,
contrato.NCLIENTE, clientes.NOMBRE,
conceptosgastos.DESCRIPCION AS NOMBREGASTO
FROM gastos
Inner Join contrato ON gastos.N_CONTRATO = contrato.N_CONTRATO
Inner Join clientes ON contrato.NCLIENTE = clientes.NCLIENTE
Inner Join conceptosgastos ON gastos.N_GASTO =
conceptosgastos.CODIGO
GROUP BY gastos.N_CONTRATO,
gastos.N_GASTO,
Ano,
contrato.NCLIENTE,
clientes.NOMBRE
HAVING gastos.N_CONTRATO = '0686-2-2006'
ORDER BY contrato.NCLIENTE, gastos.N_CONTRATO,
conceptosgastos.DESCRIPCION
) AS consulta
GROUP BY NOMBREGASTO
¿Existe alguna forma de hacer funcionar esta Select?

Problemas con TMySQLDataSource.

Publicado: Dom Oct 07, 2007 11:06 pm
por jasm
Hola Juan Jose,
¿Has probado esa SELECT desde MySQL directamente?
Saludos
Jose A. Suarez

Problemas con TMySQLDataSource.

Publicado: Lun Oct 08, 2007 12:06 am
por jasm
Mirando con más detenimiento la SELECT llego a la conclusión de que
Xailer parsea la cadena buscando el nombre de la tabla que hay detrás
del FROM y en este caso lo que hay es otra SELECT anidada dentro, por lo
que el "SHOW INDEX FROM tabla" no funciona.
Para poder hacer los procesos automáticos Update() y Delete() del
datasource, Xailer necesita averiguar que indice es el PRIMARY KEY (o en
su defecto UNIQUE), por lo que hace el SHOW INDEX.
Un saludo
Jose A. Suarez

Problemas con TMySQLDataSource.

Publicado: Lun Oct 08, 2007 6:06 am
por Rene Flores
Juan Jose:
Mi experiencia personal cuando son queries tan complejos: siempre es
mejor hacer un stored procedure y encima se ejecuta mas rapido porque es
echo en el servidor, no en el cliente.
Saludos
Rene Flores
http://www.ciber-tec.com
-------------------------
Nos vemos en Santiago de Chile el 13 de Octubre
Buenos Aires, Argentina del 3 al 5 de Noviembre.
Zamora San Martin escribió:
> Hola a todos,
>
> Estoy teniendo problemas al utilizar TMySQLDataSource con estructuras
> complejas como por ejemplo la siguiente:
>
> WITH OBJECT oGastos1 := TSQLQuery():New( Self )
> :oDataSource := AppData:oConeMySQl
> :cSelect := "SELECT NOMBREGASTO, "
> FOR n:= 1 TO LEN( aaNosGastos )
> :cSelect += "SUM( IF( ANO = " + ALLTRIM( STR( aaNosGastos[ n ],
> 4, 0 ) ) + ;
> ", IMPORTE_GASTO, 0 ) ) AS ANO" + ALLTRIM( STR(
> aaNosGastos[ n ], 4, 0 ) ) + ", "
> NEXT
> :cSelect += "SUM( IMPORTE_GASTO ) AS SUMAGASTO FROM ( "
> :cSelect += "SELECT gastos.N_CONTRATO, gastos.N_GASTO,
> YEAR(gastos.FECHA) AS Ano, " +;
> "contrato.DESCRIPCION, Sum(gastos.IMPORTE) AS
> IMPORTE_GASTO, contrato.NCLIENTE, " +;
> "clientes.NOMBRE, conceptosgastos.DESCRIPCION AS
> NOMBREGASTO " +;
> "FROM gastos Inner Join contrato ON gastos.N_CONTRATO
> = contrato.N_CONTRATO " +;
> "Inner Join clientes ON contrato.NCLIENTE =
> clientes.NCLIENTE " +;
> "Inner Join conceptosgastos ON gastos.N_GASTO =
> conceptosgastos.CODIGO " +;
> "GROUP BY gastos.N_CONTRATO, gastos.N_GASTO, Ano,
> contrato.NCLIENTE, clientes.NOMBRE " +;
> "HAVING gastos.N_CONTRATO = '" + cContrato + "' "
> +;
> "ORDER BY contrato.NCLIENTE, gastos.N_CONTRATO,
> conceptosgastos.DESCRIPCION " +;
> " ) AS consulta1 GROUP BY NOMBREGASTO"
> :lOpen := .T.
> :Create()
> END WITH
>
>
> Cuando pasa por el :Create da el siguiente error:
>
> ***************************** Registro de errores
> *****************************
>
> Fecha: 07-10-2007
> Hora: 17:15:16
> Memoria libre: 633912
> Area actual: 1
>
> ------------------------- Información del compilador
> --------------------------
>
> Versión Xailer: Xailer 1.6.6 Version 1.6
> Compilador: xHarbour build 0.99.61 Intl. (SimpLex) PCode Version: 7
> Compilador C/C++: Borland C++ 5.5.1
> Plataforma: Windows XP Professional 5.01.2600 Service Pack 2
>
> ----------------------- Información detallada del error
> -----------------------
>
> Subsistema: MySQL
> Código de error: -1
> Estado: .T.
> Descripción: You have an error in your SQL syntax; check the manual
> that corresponds to your MySQL server version for the right syntax to
> use near '(' at line 1
> Operación: TMYSQLRECORDS:QUERYALL
> Argumentos: [ 1] = Tipo: C Valor: SHOW INDEX FROM (
> Fichero:
> Código error SO: 0
>
> Pila de llamadas:
> TMYSQLRECORDS:QUERYALL (185)
> TMYSQLRECORDS:OPEN (149)
> TSQLQUERY:OPEN (308)
> TDATASET:CREATE (222)
> TSQLQUERY:CREATE (39)
> TFORM1:BUTTON1CLICK (295)
> TBUTTON:ONCLICK (0)
> TBUTTON:CLICK (99)
> (b)XCONTROL:XCONTROL (140)
> TBUTTON:COMMAND (0)
> TSCROLLINGWINCONTROL:WMCOMMAND (253)
> TFORM1:WMCOMMAND (885)
> RUNFORM (0)
> TAPPLICATION:RUN (209)
> MAIN (43)
>
>
> Esta sentecia traducida al castellano es la siguiente:
>
> SELECT NOMBREGASTO,
> SUM( IF( ANO = 2005, IMPORTE_GASTO, 0 ) ) AS ANO2005 ,
> SUM( IF( ANO = 2006, IMPORTE_GASTO, 0 ) ) AS ANO2006 ,
> SUM( IF( ANO = 2007, IMPORTE_GASTO, 0 ) ) AS ANO2007 ,
> SUM( IMPORTE_GASTO ) AS SUMAGASTO
> FROM (
> SELECT gastos.N_CONTRATO, gastos.N_GASTO, YEAR( gastos.FECHA )
> AS Ano,
> contrato.DESCRIPCION, Sum(gastos.IMPORTE) AS IMPORTE_GASTO,
> contrato.NCLIENTE, clientes.NOMBRE,
> conceptosgastos.DESCRIPCION AS NOMBREGASTO
> FROM gastos
> Inner Join contrato ON gastos.N_CONTRATO = contrato.N_CONTRATO
> Inner Join clientes ON contrato.NCLIENTE = clientes.NCLIENTE
> Inner Join conceptosgastos ON gastos.N_GASTO =
> conceptosgastos.CODIGO
>
> GROUP BY gastos.N_CONTRATO,
> gastos.N_GASTO,
> Ano,
> contrato.NCLIENTE,
> clientes.NOMBRE
>
> HAVING gastos.N_CONTRATO = '0686-2-2006'
> ORDER BY contrato.NCLIENTE, gastos.N_CONTRATO,
> conceptosgastos.DESCRIPCION
>
>
> ) AS consulta
>
> GROUP BY NOMBREGASTO
>
> ¿Existe alguna forma de hacer funcionar esta Select?

Problemas con TMySQLDataSource.

Publicado: Lun Oct 08, 2007 7:23 pm
por Juan Jose Zamora San
Gracias por respondender.
Efectivamente xailer parsea la cadena en la metodo Open() de la Clase
XMySQLRecords.
En el tipo de select complejas donde se va a mostrar la información para
un listado o un browse, deberí­a mediante una variable de instancia poder
ejecutarla sin contruir Xailer de nuevo la sentencia, pues el cursor
nunca se va a utiliar para añadir o modificar los registros, incluso no
va a ser necesario ordenarlo en los browse.
He visto la sentencia siguiente oConeMySQl:Execute( :cSelect, ,
@aBorrar1 ), que nos retorna un array multidimensional con el
resultados de la Select, pero tiene menos funcionalidedes que la clase
TMySQLRecords.
Rene, en cuanto a los stored procedure, no puedo utilizarlo pues el
cliente utiliza la versión 4 de Mysql.
¿Serí­a posible desarrollar esta funcionalidad por el equipo de Xailer?
José Alfonso Suárez Moreno escribió:
> Mirando con más detenimiento la SELECT llego a la conclusión de que
> Xailer parsea la cadena buscando el nombre de la tabla que hay detrás
> del FROM y en este caso lo que hay es otra SELECT anidada dentro, por lo
> que el "SHOW INDEX FROM tabla" no funciona.
>
> Para poder hacer los procesos automáticos Update() y Delete() del
> datasource, Xailer necesita averiguar que indice es el PRIMARY KEY (o en
> su defecto UNIQUE), por lo que hace el SHOW INDEX.
>
>
> Un saludo
>
> Jose A. Suarez

Problemas con TMySQLDataSource.

Publicado: Lun Oct 08, 2007 8:17 pm
por ignacio
Juan José,
Te recomiendo que de momento utilices el método QueryArray() y pases el
contenido a un TMemDataset. Intentaremos mirarlo cuanto antes.
Un saludo,
--
Ignacio Ortiz de Zúñiga
http://www.xailer.com
"Juan Jose Zamora San Martin" <juanjosezamoras@gmail.com> escribió en el
mensaje news:470a6787$[email=1@ozsrv2.ozlan.local...]1@ozsrv2.ozlan.local...[/email]
> Gracias por respondender.
>
> Efectivamente xailer parsea la cadena en la metodo Open() de la Clase
> XMySQLRecords.
>
> En el tipo de select complejas donde se va a mostrar la información para
> un listado o un browse, debería mediante una variable de instancia poder
> ejecutarla sin contruir Xailer de nuevo la sentencia, pues el cursor nunca
> se va a utiliar para añadir o modificar los registros, incluso no va a ser
> necesario ordenarlo en los browse.
>
> He visto la sentencia siguiente oConeMySQl:Execute( :cSelect, ,
> @aBorrar1 ), que nos retorna un array multidimensional con el resultados
> de la Select, pero tiene menos funcionalidedes que la clase TMySQLRecords.
>
>
> Rene, en cuanto a los stored procedure, no puedo utilizarlo pues el
> cliente utiliza la versión 4 de Mysql.
>
> ¿Sería posible desarrollar esta funcionalidad por el equipo de Xailer?
>
>
>
>
> José Alfonso Suárez Moreno escribió:
>> Mirando con más detenimiento la SELECT llego a la conclusión de que
>> Xailer parsea la cadena buscando el nombre de la tabla que hay detrás del
>> FROM y en este caso lo que hay es otra SELECT anidada dentro, por lo que
>> el "SHOW INDEX FROM tabla" no funciona.
>>
>> Para poder hacer los procesos automáticos Update() y Delete() del
>> datasource, Xailer necesita averiguar que indice es el PRIMARY KEY (o en
>> su defecto UNIQUE), por lo que hace el SHOW INDEX.
>>
>>
>> Un saludo
>>
>> Jose A. Suarez

Problemas con TMySQLDataSource.

Publicado: Mar Oct 09, 2007 10:44 pm
por Juan Jose Zamora San
Gracias Ignacio, cada dí­a estoy más contento de haber elegido xailer
para trabajar.
Saludos.
Ignacio Ortiz de Zúñiga escribió:
> Juan José,
>
> Te recomiendo que de momento utilices el método QueryArray() y pases el
> contenido a un TMemDataset. Intentaremos mirarlo cuanto antes.
>
> Un saludo,
>