jueves, mayo 08, 2008

Que alguien me explique.... porque no lo comprendo

Como diría mi admirado Condorito (saludos Chile) ¡ Exijo una explicación !.

Me gustaría saber.... ¿ porque muchos de los programadores de (x)Harbour y sus entornos visuales quieren usar una base de datos basada en SQL ? ..... ¡¡¡¡ SI NO VAN A USAR EL SQL !!!!!!!

¡ Que alguien me explique por favor !

Abundan las preguntas en los foros del tipo: ¿ como uso MySQL con xHarbour ?, ¿ Puedo leer tablas de Oracle con xHarbour ?, Quiero cambiar de base de datos y usar SQL Server en vez de DBFs, ¿ como lo hago ?, estas preguntas se repiten a puños en los foros..... tooooodo el mundo quiere usar un SQL ¡ Pero muchos programadores lo quieren usar o lo usan como si fueran DBFs ! como sucedería en la tira cómica de Condorito .... ¡ PLOP !.

Que alguien me explique porqué, si el producto se llama MySQL, SQL Server, Postgre SQL,..... ¿ porqué "·%&·$"!"·@# lo quieren trabajar como si fuera un DBF y no por SQL?

Y me respondo yo mismo: porque no conocen el lenguaje SQL, lo cual me parece increíble ya que SQL es un lenguaje de programación que se basa básicamente en 7 instrucciones, no entiendo entonces como un programador de (x)Harbour que se aprende mas de 20 comandos de Xbase, no puede aprender a usar 7 estúpidas instrucciones: SELECT, INSERT, UPDATE, DELETE, DROP, CREATE, ALTER.

¡ Que alguien me explique !

Es como comprarse un Ferrari sin saber conducir ni tener licencia, o lo que es peor, es comprarse el Ferrari y pretender conducirlo como si fuera una bicicleta, porque no sé conducir un coche, pero la bicicleta la llevo bien.

Lo peor de todo es que (x)Harbour fomenta seguir trabajando del modo equivocado con herramientas como el RDDSQL o el ADORDD.... vamos a ser serios por favor, si vamos a clavar un clavo en la pared, vamos a usar un martillo, no la suela del zapato, si es una herramienta SQL, vamos a trabajarla como SQL, no con parches ni apaños con el pretexto de "no conozco el lenguaje SQL", aprender SQL no tiene la menor complicación, unas 3 tardes de lectura y listo, no digo que te vas a volver un experto, pero si podrás comenzar a explotar a SQL.

Hoy por ejemplo estaba revisando el foro de (x)Harbour y un colega preguntaba porqué no le funcionaba un SET RELATION con el RDDSQL y MySQL..... ¿ perdón ?..... ¿ como para qué tendrías que hacer un SET RELATION con MySQL si con un simple query (instrucción SQL) puedes obtener el resultado que necesitas ?, eso no es matar pulgas a cañonazos, es matar microbios con misiles.

Los SQL son bases de datos RELACIONALES, es decir, las relaciones son parte de su naturaleza y las pueden resolver directamente, tú no tienes porqué hacer el trabajo del servidor, si no haz aprendido eso, apaga y vámonos, regresa a los DBFs, aprende a usar SQL y cuando sepas SQL, regresa, no te vas a arrepentir, pero por favor, pretender trabajar un SQL como si fuera un DBF es un desperdicio de recursos, una pérdida de tiempo, de líneas de código y de esfuerzo, créeme por mas que lo intentes, el mar no cabe en un vaso, solo cabe un poquito.

Si estás decidido a aprender SQL, te advierto una cosa.....SQL es una tecnología que causa adicción, es como el iPod, una vez que te enganchas..... a ver como te lo quitas de encima.... si no me crees, trabaja un mes con SQL, y te aseguro que nunca mas querrás volver a usar un DBF, cualquiera que haya hecho el cambio no me dejará mentir.

Quizá la parte mas complicada de trabajar un SQL es como leer el "cursor" es decir, como acceder a los datos devueltos por la ejecución de un query, para hacer las cosas mas simples de entender, un "cursor" equivale al "alias" de un DBF, y para ello, ADO (Activex Data Objects) se pinta solo, conjunta lo mejor de 2 mundos: el Poder del SQL, con la facilidad de uso del modelo Xbase, automatizando mucho del trabajo de acceso a los servidores de datos.

ADO tampoco es complicado de entender, son 3 objetos fácilmente accesibles desde xHarbour por medio de OLE (Object Linking and Embeding), si quieres saber mas sobre ADO, mi amigo Gabriel Maimò tiene estupendos artículos al respecto en su blog: BielSys.

Así que para que gastar en herramientas externas como RDDSQL, Mediator, etc, cuando puedes usar todo el poder del SQL con un rato de estudio y además gratis usando (x)Harbour y te funciona tanto para modo consola como para entrono gráfico.

Otro punto importante cuando trabajas con una base de datos SQL: Las bases de datos de este tipo son poderosas por la arquitectura sobre la cual están diseñadas: son Cliente / Servidor, ojo a la ultima palabra: SERVIDOR.

Mientras te comienzas a sentir cómodo con el SQL, entiendo que programes los queries (instrucciones SQL) como parte de tu código fuente, pero eso solo será al principio, la idea es PONER A TRABAJAR AL SERVIDOR (por eso se llama Cliente / Servidor), para ello se inventaron los "Procedimientos almacenados" ó "Stored Procedures", ¿ que son ?, pues son como "funciones" de Clipper, pero que están escritas en SQL, y están almacenadas en el servidor como parte de la estructura de la base de datos, esto facilita muuuuuuucho la programación del SQL, porque no tienes mas que llamar a los procesos almacenados desde tu código fuente con parámetros, si tu quieres hacer algún cambio en un proceso almacenado, no tocas el código fuente de tu programa (x)Harbour, lo modificas directamente en el servidor de la base de datos, eso es parte de la "arquitectura de 3 capas".

Resumiendo: Si estas usando un SQL Cliente / Servidor (= 100%) , sin la parte del SQL ( -50%), ni la parte del Servidor (-25%), lamento informarte, que estás usando solo un 25% de todo lo que podrías hacer si supieras explotar toda la herramienta, ahora imaginate, si estás usando SQL Server, sin parte del SQL ni la parte del Server......pues nos ha jodido, ¡ No estas usando nada ! y si no estás usando nada ...... ¿ para que quieres usar un SQL ?.

¡ Que alguien me explique !

9 comentarios:

Anónimo dijo...

Veamos René:

"¡ Que alguien me explique !"

Llevo mas de 30 años de haber programado en diferentes lenguajes, incluyendo algunos celebres desconocidos (Algol, Lisp), cuando decidí independizarme (porque ya no me daban chamba de director) había olvidado la programación y encontré Clipper.

Traía la idea de los 'Mainframes' y me costó trabajo entender las PCs, quise apostarle al Proceso Distribuido, estoy satisfecho con mas de 200 clientes básicos (y 3000 registrados o posibles clientes).

Bueno. Llevo mas de 15 años trabajando con DBFs y a mis 50s no pretendo cambiar, tal vez si tuviera 10 años menos y un nuevo desarrollo buscaría otras herramientas y si son gratuitas mejor.

Hoy le he apostado a SQLRDD y lo veo estable, tal vez me equivoque, pero hasta hoy le veo una respuesta satisfactoria de acuerdo a mis requerimientos. Solo he cambiado unas cuantas líneas para conectarme a la base de datos relacional que se use y listo.

Como tu dices los comandos que se requieren para acceder a SQL son pocos, no me asusta el uso de ellos, me asusta cambiar mas de 100 PRGs a ese viejo esquema (di cursos de eso), pero me resisto a regresar, me agrada que haya desarrolladores que me faciliten en manejo de la información guardada en DBFs a traves de un RDD, deja que esa herramienta se encargue de convertir lo que haga falta.

En nuestra última conversación me comentabas acerca de la lentitud en los procesos y lo he comprobado, pero sucede que en los procesos que se comportaban lentos se estaba abusando de las bondades de xBase, exceso de filtros y recorridos inútiles de tablas, después de depurar estas situaciones se están comportando de manera similar al acceso directo con SQL. Limitantes, servidor, ancho de banda y tiempos de transferencia (supongo).

Espero y estos comentarios no causen mella.

Y (después de algunos tequilas, que me animaron a escribir esto) sigue abierta mi invitación a unos buenos cortes y un buen vino acá en casa.

Finalmente, te diré que me agrada como escribes tus comentarios y estoy dispuesto a cubrir tus honorarios para que escribas algo sobre mis productos.

Un abrazo!

Alfredo Arteaga

Rene Flores dijo...

Alfredo:

Yo no he dicho que el RDDSQL no funcione, simplemente he dicho que no es la forma correcta de trabajar.

Digamos que si vamos a clavar un clavo, tendriamos que usar un martillo, que seria el SQL, el RDDSQL seria una suela de zapato diseñada para clavar clavos, digamos que es una forma eficiente de hacer mal las cosas, prueba de ello es que funciona, aunqe no sea como se deben de hacer las cosas.

Comentando esto con un colega al calor de una taza de cafe me dijo algo muy interesante, es una forma valida de trabajar, pero no es la optima.

Tocas un punto muy interesante "me austa cambiar mas de 100 programas", a eso me refiero, que por flojera, decidia o miedo no nos atrevemos con 7 instrucciones.

Mi primer proyecto con SQL fue para Zurich compañia de seguros, hace mas de 7 años, dada la delicadeza del sistema y por requerimientos gubernamientales, forzosamente tenía que trabajar con SQL para Informix 6, y yo no tenia npi.

Sucede que tuve que aprender en una semana, ¿ y sabes una cosa ? me encantó, el proyecto duró como 3 meses, al final del proyecto, me disgustó mucho tener que volver a los DBFs.

Probablemente SQL sea un sistema que se inventó en los 70's, sin embargo la tecnología ha eficientado el uso de SQL a nivel micros, por otro lado tienes el poder de ADO, que como sabrás, mezcla lo mejor de los dos mundos.

Te puedo asegurar que si eficientas tu CA-Windows para SQL, usando ADO y procesos almacenados, vas a reducir mas de un 60% del codigo de manejo de tablas de tu sistema.

¿Merece la pena ?, por su puesto, no me creas a mí, pregunta a todos los usuarios de xHarbour que trabajan con ADO y con SQL directamente y te dirán que te vas a ahorrar mucho trabajo.

Juan José dijo...

René, estoy de acuerdo contigo en parte:

En cuanto que no conocen el lenguaje SQL, …. Que se basa básicamente 7 instrucciones. Efectivamente René se basa en 7 instrucciones que los “distintos motores de SQL” lo utilizan en lo básico igual, pero tiene sus sabores. Me explico:
- Sentencia SELECT con LIMIT:
o MySQL, la permite. Puedes poner SELECT * FROM cliente LIMIT 10,20 y te traerías los registros del 10 al 20 de la select.
o Access y SqlServer, no tiene Limit y utiliza para ello, TOP pero con una desventaja, sólo te permite un operador, por ejemplo TOP 20, con lo que te traería los 20 primeros registros. (Se podrían utilizar Subselect para traernos al igual que el anterior los 10 registros )
 Si utilizamos AdoDb y Xailer podríamos utilizar nMaxRecords para indicar el número de registros a traer. Pero otra vez se comporta de distinta manera en Acces que SQlServer, en el primero no lo permite y lo ignora y en el segundo es compatible.
- Sentencia SELECT con IF
o ACCESS, SqlServer y MySQL la permite. Podríamos hacer lo siguiente:
SELECT
YEAR( Fecha ) AS ANO,
codigoproveedor,
Proveedores.Nombre,
Sum( IIf( Month( Fecha ) = 1, TotalFactura, 0 ) ) AS Enero,…..

o SQLite no lo permite.
Por tanto René, no sólo es necesario conocer las 7 sentencias, sino conocer el motor con el que trabajamos y de la herramienta que disponemos como cliente.
Cuando se empieza con motores de SQl proveniente del mundo de la DBF, te hablo por experiencia, lo lógico es utilizar las Select para traerte todos los registros de una tabla, al igual que con los USE. Esto tiene varios inconvenientes que te das cuenta luego, cuando llevas un tiempo y empiezas a meter cientos de registros:
o Si estamos en local, nos funciona todo correcto, va a una velocidad de vértigo. Aunque tengamos varios miles de registros.
o Si estamos en una red local, nos funciona aceptable.
o Pero si estamos en una Wan, nos damos cuenta que no podemos utilizarlo de esa forma.
Y es entonces cuando surge otro dilema:
Mis clientes están acostumbrados a que les muestre un Browse con todos los registros que tiene una tabla, para seleccionar o situarse en el registro que necesitan, vamos una cosa normal en Dbf, es imposible, digo imposible de hacer en Sql cuando tenemos varios miles de registros. Te pongo un ejemplo de cómo lo hago con Xailer, para que se entienda:
- Creo un formulario.
- Creo un objeto oMySQLDataSource o bien un AdoDataSource y le indico la conexión, y abro el cursor.
- Creo un objeto oSQLQuery e introduzco la sentencia Select, por ejemplo SELECT * FROM Clientes.
- Creo un objeto Tdbbrowse para poner los datos que me he traído con la Select anterior. Cuando tienes pocos registros, ¡Fenómeno que bien funciona SQL! Y empiezas a engancharte como tú dices a SQL, pero cuando se empieza a llenar la tabla, tus clientes empiezan con la siguiente frase: “Tardo 2 segundos en tener el control y poder filtrar los registros…..” para después convertirse en tres, cuatro, cinco, etc. Al final no sabes si tirar otra vez de las dBf o seguir con SQl.

De pronto te das cuentas nMaxRecords y decides ponerla en uso, el cliente le has puesto MySql, y resulta “joder” que no hace ni caso a esa propiedad. Investigas la clase y te das cuenta que es muy fácil modificarla para poner un limit y que de nuevo va como una bala. ( ojo utilizando un datasource de Sql, cuando ponemos un filtro en el browse se vuelve a lanzar la Select, perfecto como ya tengo el limit es fabuloso.

En cuanto utilizamos ado, es imposible, se comporta de distinta forma, ya no lanza la Select sino que internamente utiliza un filtro de los datos que tienes en el cursor, con lo cual el nMaxRecords tampoco funciona bien. Y si utilizamos Access no podemos, “fácilmente” modificar la clase para que ejecute de nuevo la sentencia ahora con el TOP correpondiente.


Todo esto, para explicar la sentencia SELECT, me faltan las vistas y los procedimientos almacenados.

- Vistas no todos los motores de bases de datos las tienen, por ejemplo Mysql las trae a partir de versión 5.
- Procedimientos almacenados, es imposible digo imposible traspasar un procedimiento de mysql a SqlServer, etc.
Por todo ello y sin quererme enrollar demasiado:
- Lo lógico cuando trabajas con SQL es dominar un “motor”, digo un solo motor para poder utilizar un 50% de su potencia. Utilizar más del 50% nos llevaría años de estudio.
- Pensar que lo que hagáis, para un motor determinado, lo más seguro que sea incompatible con otros.
- Tiempo para empezar a aprovechar SQL:
o Básicamente, unos 7 días para aprender los comandos.
o 6 Meses para utilizar esos comandos bien.
o 1 año, para aprender procedimientos almacenados, vistas, etc.
Y ahora René, viene la pregunta ¿Es fácil o difícil acostubrarse a SQL? La respuesta Rene, es que es muy compleja.

Anónimo dijo...

Respecto a lo de consola, cómo puedo hacer para ver los resultados de mis consultas SQL con el TBRowse?

De antemano, mucha gracias.

Salu2,
GVS

Rene Flores dijo...

Juanjo:

Te doy la razón y no.

La especialización es un punto importante.

Si tu haces un software para un SQL no se trata de hacerlo para TODOS los SQL del mundo mundial.

Si tu vendes un software comercial, entonces usa un solo SQL, por ejemplo MySQL, muchas empresas venden software comercial para tal o cual Servidor de Datos y es responsabilidad del cliente tener dicha base de datos, no lo ofrecen multibase de datos, porque eso es un meterse en un berenjenal

En proyectos especiales estoy de acuerdo en que te sujetes a los requirimientos del cliente, pero las variaciones del lenguaje son minimas y están documentadas, de hecho SQL es un lenguaje estandar ANSI desde 1977, es decir, que todos los SQL tienen que soportar un set de instrucciones basicas, que tienen que comportarse igual en todos los productos.

En los tiempos del DBASE viviamos con una especie de "procesos almacenados", que eran nuestros PRGs, la unica diferencia ahora es que esos PRGs se llaman stored procedures y son parte de la estructura de la base de datos.

Y perdón que insista, si quieres usar un SQL por las ventajas que te da, pero no estas dispuesto a investigar y a aprender como explotarlo, es como querer aprender a hablar inglés, pero nada mas querer aprender a leerlo, porque únicamente me interesa leer libros, no me interesa hablar con la gente ni escuchar lo que me tenga que decir.

Si aprendes un idioma, la idea es que lo escribas, que lo hables y que entiendas lo que la gente trata de comunicarte en ese idioma.

¿ no es cierto ?

Rene Flores dijo...

Para visualizar los resultados del un SQL en un TBrowse de xHarbour modo consola:

1) Obtener el RecordSet via ADO

2) Crear el objeto TBrowse y cambiar los bloques de codigo que definen los movimientos para ir arriba y abajo del browse, por los metodos de ADO que definen los equivalentes:

oBrw := TBrowseNew(0,0,24,79)
oBrw:goBottomBlock := {|| oRecordSet:MoveLast()}
oBrw:goTopBlock := {|| oRecordSet:MoveFirst()}
oBrw:SkipBlock := {|nSkip| RecordSetSkip(nSkip)}

3) Reescribir la funcion de desplazamiento interno del browse (RecordSetSkip):

Static Function RecordSetSkip(nSkip)
LOCAL nRec := oRecordSet:AbsolutePosition
oRecordSet:Move( nSkip )
IF oRecordSet:EOF; oRecordSet:MoveLast(); ENDIF
IF oRecordSet:BOF; oRecordSet:MoveFirst(); ENDIF
Return (oRecordSet:AbsolutePosition - nRec)

4) finalmente, definir las columnas del TBrowse usando la coleccion FIELDS del RecordSet:

oBrw:AddColumn(TBColumnNew("iatacode",{|| oRecordSet:Fields(0):value}))
oBrw:AddColumn(TBColumnNew("Agentype",{|| oRecordSet:Fields(1):value}))
oBrw:AddColumn(TBColumnNew("Channelcod",{|| oRecordSet:Fields(2):value}))
oBrw:AddColumn(TBColumnNew("Agentname",{|| oRecordSet:Fields(3):value}))
oBrw:AddColumn(TBColumnNew("Citycode",{|| oRecordSet:Fields(4):value}))
oBrw:AddColumn(TBColumnNew("Areacode",{|| oRecordSet:Fields(5):value}))

5) El ciclo (bucle) de estabilizacion del TBrowse funciona exactamente igual a como se haría con un TBrowse normal para el DBF:

DO WHILE .T.
oBrw:FORCESTABLE()
tecla := INKEY()
IF oBrw:HITBOTTOM .OR. oBrw:HITTOP
?? CHR(7)
oBrw:HITBOTTOM := .F.
oBrw:HITTOP := .F.
ENDIF
DO CASE
CASE tecla = K_ESC
Exit
CASE tecla = K_UP
oBrw:REFRESHCURRENT()
oBrw:UP()
CASE tecla = K_DOWN
obrw:REFRESHCURRENT()
obrw:DOWN()
CASE tecla = K_PGUP
obrw:REFRESHCURRENT()
obrw:PAGEUP()
CASE tecla = K_LEFT
obrw:REFRESHCURRENT()
obrw:LEFT()
CASE tecla = K_RIGHT
obrw:REFRESHCURRENT()
obrw:RIGHT()
CASE tecla = K_PGDN
obrw:REFRESHCURRENT()
obrw:PAGEDOWN()
CASE tecla = K_CTRL_HOME
obrw:REFRESHCURENT()
obrw:GOTOP()
CASE tecla = K_CTRL_END
obrw:REFRESHCURRENT()
obrw:GOBOTTOM()
ENDCASE
ENDDO

Rene Flores dijo...

Anonimo:

Los comentarios críticos son muy bienvenidos en este blog.

Los comentarios ofensivos o insultantes no.

Por eso tu comentario no ha aparecido.

Anónimo dijo...

Hola Rene

Yo tengo unos 6 años utilizando SQL como se debe y si al principio fue dificil el pensar de manera diferente a los DBF's pero se puede comenzar con los listados.

Una vez que comienzan a dominar algo de SQL van a ver que es muy fácil y mas directo.

Supongo que cuando ustedes utilizan el RDD y tienen un comando asi:
USE xTabla

El RDD lo cambia por un
SELECT * FROM xTabla

Ahora no se si se han hecho pruebas de tiempo respuesta pero para mi creo que si debe de haber un pago por el estar utilizando RDD en vez de sentencias SQL directas.

Saludos
Ramiro

Anónimo dijo...

Aclarando un poco:

Primero, el tradicional DBF, opción de facto y muy util, mientras las cosas quedaron en, digamos, sistemas poco concurrentes. En cuanto a muchos registros, he tenido archivos con medio millón y no hubo corrupción en los idx, cdx ni en los DBF.

Sistemas SQL, cuando la cosa va a mayores, no solo por la cantidad de registros si no, por concurrencia y transaccionalidad.

Bien, separadas muy rapidamente ambas situaciones, ¿es dable tener programas para múltiples DB?

¿Puede ser sugerente (para nada nuevo) el crear conversores universales (RDD)? que, por ejemplo, me permitieran decir para cada USE, que tabla y de donde estoy leyendo. Luego, al realizar consultas, estas se resuelvan en dichos motores. Resultado: nuestros sistemas pueden acceder datos de múltiples plataformas (o por lo menos, las mas comunes) en forma transparente. En un proyecto así, con tener acciones CRUD (sin JOIN ni superpoderes como en Oracle), se daría un salto muy grande y la pérdida por no usar "otras bondades" no sería tan grave. Y de paso, se accedería igual que hasta ahora. Al dar commit, se debiera indicar en que sistema se desea hacer. Ni que decir si, al hacer USE, indicaramos nombres simbolicos que se resuelven en archivos.ini externos y por tanto configurables.
Y al final ¿de que serviría esto?
1) nuestros sistemas se adaptarían sin cambio de código.
2) podríamos adoptar DB mas potentes y multiplataformas o nuevas que aparezcan. (no olvidar que clipper casi desaparece. Las DB, también)
3) adaptarnos al cliente, si ya cuenta con una DB contratada y no quiere manejar otra.
4) vender nuestro sistema con su DB de facto pero, pudiendo escribir rutinas de acceso/envío de datos a pedido para otras DB, sin modificar el núcleo de lo que vendemos.
Solo eso, un aporte mas.