FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#21
|
|||
|
|||
...todo un misterio...¿no tendra algo que ver el nombre de la tabla?...bueno, ya nos diras. Saludos y suerte.
|
#22
|
||||||||||
|
||||||||||
¡Hola a todos!
Descargué la biblioteca de componentes Mercury Database Objects —MDO— (la misma versión que está usando Sick Boy, según me comentó), para echar un vistazo con mayor cercanía, específicamente sobre lo que se ha comentado de las unidades MDOSQL.pas y MDOUtils.pas (lo del nombre de cursor aleatorio, vaya), comparando diferencias con las unidades equivalentes nativas IBSQL.pas y IBUtils.pas de los IBX. Cita:
1. El nombre de un componente (propiedad Name) es una cadena vacía durante su construcción. A menos que el constructor realice, directa o indirectamente, una asignación de valor a la propiedad Name, no tiene sentido usarla como parte de una expresión dentro del constructor. 2. Los creadores de MDO movieron esa sentencia al método Prepare, como bien lo señalaste, pero en los IBX sí está habilitada en el constructor de TIBSQL, por lo que, en ese caso, el nombre del cursor siempre será solamente lo que devuelva la función RandomString (un número aleatorio de 8 dígitos). Un dato importante para los usuarios de IBX. 3. Esto me hace pensar, y trato de recordar si lo que voy a mencionar es cierto, que en versiones más antiguas de Delphi, al agregar un componente a un formulario o módulo de datos en tiempo de diseño, dicho componente obtenía su nombre predeterminado ("Label1", "IBSQL1") por medio del constructor Create de TComponent. Si alguien tiene Delphi 5 o anterior y algo de tiempo para comprobar ésto definiendo e instalando una clase de componente de prueba que muestre su nombre como última sentencia del constructor, se lo agradecería. 4. Los creadores de MDO movieron la sentencia al método Prepare, con el argumento de "if you create the MDOSQL dynamically, the name is not assigned in the create and the cursor is only based on a 'random' number". Es claro que se dieron cuenta de lo mismo que comenté anteriormente (desde X versión de Delphi, o quizá desde siempre, la propiedad Name no tiene valor durante la ejecución del constructor). Pero asumen, o dan por recomendado, que debe asignarse un valor a la propiedad Name del objeto antes de ejecutar la consulta para que el nombre del cursor quede más rico y sea menos probable que se repita, lo cual es sencillo si el componente es agregado en tiempo de diseño o lo instanciamos nosotros mismos y enseguida le damos valor a Name. Sin embargo, la clase común TMDOCustomDataSet, al igual que sucede en los IBX, crea varias instancias internas de estos objetos SQL sin darles valor a su propiedad Name (a no ser que lo haga en algún punto del código que no logro ver). Así pues, con el nombre del cursor (FCursor) generado en el constructor Create o en el método Prepare, éste siempre será un número de 8 dígitos, a menos que se trate de un componente TMDOSQL que nosotros mismos hayamos preparado. Cita:
Cita:
Cita:
Cita:
Cita:
Aun cuando ya no suelo usar este tipo de componentes especializados en un motor (tarde o temprano te enamoras de dbExpress con TClientDataSet ), creo que cambiar de componentes sería algo aventurado en este momento. Cita:
Cita:
Te sugiero emplear la misma función, RandomString, pero con un valor de 1 en lugar de 8, para intentar reproducir las condiciones que generan la excepción. Cita:
Cita:
Como punto y aparte, y a pesar del análisis anterior, yo no descarto que la causa del problema pueda ser otra cosa. Esperemos a ver qué nos trae Sick Boy... Un abrazo sin nombre. Al González. P.D. Algo más: ¿alguien conoce el ámbito que tienen los nombres de cursores? ¿Es por conexión (programa), por máquina cliente, globales para todos los clientes...? Pienso que deberían ser por conexión/transacción, pero quisiera confirmarlo. Última edición por Al González fecha: 14-12-2008 a las 10:39:45. |
#23
|
||||
|
||||
Ya sé que no es excusa, pero los creadores de MDO son portugueses, al menos el creador original.
Cita:
Si los de borland no lo han solucionado... no voy a ser yo quien lo haga . No he tenido tiempo de mirar el código, amén de que no uso MDO ahora mismo. Por otra parte lo de GUID fue lo primero que pensé, pero dado que no sabía que tal rebuscado era el código (si estaba dentro de threads, secciones críticas o "cosas más raras aún") preferí ser cáuto y no decir nada. También es posible que los MDO se usarán, como bien dices, en versiones más antiguas de delphi donde no estuviese disponible el GUID. Cita:
Y las disculpas anticipadas, era por este comentario: "Entonces, no usarás la JVCL ¿verdad? siguiendo tu línea ¡¡es descabellado usar la JVCL!! ¡¡ está plagado de todo's y not implemented yet!!". En fin, no puedo aportar nada de valor al hilo y no quiero desvirtuar más de lo necesario, así que con el permiso de venia, me retiro. ... bueno... quizás sí... Sick Boy, si quieres un TMDOAutoDataset, es decir, un componente que se crea en ejecución y que dando la sql de selección genera automáticamente las demás sqls de inserción, borrado y actualización, dilo y subo el archivo. Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#24
|
|||
|
|||
Cita:
Cita:
Cita:
Sobre el hecho de que solo ocurra en una maquina, y esta sea la del cliente, es lo que mas me intriga. Pense si el nombre de la tabla pueda tener algo que ver, o incluso la tabla de codigos |
#25
|
||||
|
||||
Ole, no se por donde empezar.
Cita:
Efectivamente, el prefijo Fname ayudaria mucho a crear cursores unicos. Cita:
He seguido investigando en el codigo MDO, y veo que TMDOSQL no tienen por ninguna parte la propiedad Fname, mientras que la clase TMDOXSQLVar si que la tiene. Por lo que veo es la unica clase con esa propiedad. Por ahora, no veo la forma de darle valor a Name, creo que esto mejoraria la situacion. Acabo de pasar el randomString(1), es decir, los cursores son un numero de un digito, name sigue siendo nulo. Como era de esperar la aplicacion arranca con problemas, pero ya puedo reproducir el error facilmente. Cita:
En este caso, el cliente realiza un uso bajo de la aplicacion, hay clientes que le superan por mucho. Aproximado, no se, quizas 500 sentencias por hora. Algunas de las operaciones habituales requieren unos 6 cursores. Cita:
Acabo de descubrir algo interesante. Le he puesto transaction.name y sql.text al showmessage que me indicaba cuando un cursor nuevo es creado. Tambien he puesto un showmessage para ver los cursores que no son nuevos. Los cursores son de 1 digito. Los cursores reutilizados funcionan bien. Los cursores nuevos, nunca tienen nombre, y parece que el ambito es la transaccion, ya que si haces un comit, la proxima vez que se abre el cursor aparece como NUEVO y le asigna un nuevo numero sin problemas. Diferentes transacciones y mismos numeros hasta ahora todo bien. La sorpresa es que los select internos tipo "Select F.RDB$COMPUTED_BLR, F.RDB$DEFAULT_VALUE ....." no llevan asignado un nombre de transaccion. Cuando comienzan a abrirse estos cursores, en pocas sentencias se produce el error, por ejemplo, detecta que el cursor 1 ya esta declarado y salta la excepcion. Cada vez que vuelva a aparecer ese cursor 1 en la transaccion "sin nombre" saltará el error. He puesto un timer que repite una sentencia SQL simple, el select mio se ejecuta bien en la transaccion que tiene asignada. Al ejecutar la sentencia interna que te devuelve los valores por defecto, campos calculados, .... el cursor asignado en los 10 ultimos select ha sido el 1 (poco aleatorio, pero bueno) y cada vez que sale el 1 da error en ese select, no en el mio. Si aleatoriamente sale un numero distinto del 1 la sentencia funciona correctamente. Si cierras la aplicacion y la vuelves a abrir comienza todo, por lo que creo que el ambito del cursor es a nivel de transaccion/conexion. |
#26
|
|||
|
|||
Cita:
Si, uso JVCL, y si, he visto las lindezas que tiene y he aprendido a vivir con ellas. Que yo no digo que sean una mierda de componentes, es solo que esto me parece "una chapuza" por el problema concreto que estoy teniendo. Ademas, que existan componentes peores o mejores no es excusa. Como dice Al, mejoraron la solucion de los IBX, un punto a su favor, y si bien yo anteriormente calificaria a los componentes como "EXCELENTES", ahora entenderas que no pueden tener la misma nota, y no sabria que nota ponerles, quizas utilizarlos sea un poco arriesgado. Cita:
Cita:
Mismo nombre de tabla, misma tabla de codigos, todo igual. |
#27
|
|||
|
|||
A sugerencia de Coso, le añadi un timetostr(now) al nombre del cursor. Le añadi tambien un numero aleatorio de 1 digito y ya no aparece el error en mi equipo, el lunes lo probaré en el cliente, pero con la hora y 8 digitos aleatorios.
Esto deberia ser suficiente para que no se repitan. Vale, ya lo se, cada 24 horas.... el tiempo comienza a repetirse, pero los 8 digitos aleatorios deberian ser suficientes. He pensado en añadirele tambien el dia del mes, ¿que pensais vosotros?? PD: Dejar un espacio en blanco en el nombre del cursor lo trunca. Por ejemplo "cursor, portate bien" quedaria como "cursor," |
#28
|
|||
|
|||
Sobre el 'name', creo que andas equivocado: después del create es cuando se le asignan los valores del inspector de propiedades al objeto, y seria muy raro que no se asignara nombre si haces, por ejemplo
si esto te muestra una cadena vacia, hay un problema gordo Sobre lo del tiempo, usaria todas las cifras de fecha y hora : nunca son iguales
s tendria que ser '21032003130923' Cita:
Última edición por coso fecha: 14-12-2008 a las 17:31:05. |
#29
|
|||
|
|||
OK Coso, me ha sido de mucha ayuda.
Si, tengo un randseed, y es lo que me anda provocando el problema, lo tengo bastante claro. Tengo un timer que encripta y envia una información cada cierto tiempo. Es algo opcional, parece que solo este cliente lo tiene activado. Al encriptar utilizo una rutina que inicializa el randseed. Cuando hicimos las pruebas, no esperamos el tiempo suficiente para que los cursores empezaran a repetirse, asi que todo parecia estar correctamente. Ya sabemos las "determinadas circunstancias" en las que los MDO daran problemas. Es mas, creo que los IBX tambien tendran el mismo problema. La solucion pasa por eliminar los cursores aleatorios y convertirlos en unicos. Lo de que la fecha y la hora no se repiten es relativo. Si el cliente modifica la fecha y hora del windows hacia atras comenzaria la pesadilla. Tambien con los cambios de horario de verano/invierno. Lo ideal seria conseguir numeros unicos, quizas utilice GUI, si es que no se ve afectado por el randseed Voy a hacer las pruebas activando la opcion que reinicia la semilla y os comento. |
#30
|
||||
|
||||
Yo no gastaría más tiempo en el randseed, está claro que al ejecutarlo reinicializa la semilla y es cuando empiezan los problemas.
¿puedes crear un simple número Int64 e ir incrementándolo cada vez que se crea un nuevo cursor? Obviamente lo pasas a string y ya tienes números bastante grandes. Incluso puedes guardarlo en un archivo .ini y continuar con él hasta cierto número predeterminado, después de eso lo reinicias: Los GUID son creados por Microsoft y por ello no sabemos cómo están hechos, (al menos yo). Ya puesto, puedes mezclar y el formato de fecha y hora, incluyendo milisegundos con un Int64:
El problema según creo entender son esos cursores que acceden a las tablas de sistema ¿no? Suerte
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. Última edición por Lepe fecha: 14-12-2008 a las 17:53:19. |
#31
|
|||
|
|||
Lo que propone Lepe estaria bien, pero resulta que el name nunca llega hasta el codigo donde se crea el cursor.
He puesto un comprobante para que salte si al crear el cursor name<>'', y ninguno de los cursores recibe valor en name. Ni los puestos en tiempo de diseño, ni los creados en ejecucion (añadiendo query.name explicitamente), tanto querys como datasets. Creo que Al Gonzaléz me advirtió de que esto pasaria, aunque no se como lograr que funcione. Yo pude reproducir el error con cursores de un solo digito, y las sentencias más afectadas eran las de tablas de sistema, ya que no se en que transacción estan, ni cada cuanto tiempo se abren y cierran. Con las sentencias SQL que creo yo acostumbro a abrir la transaccion, ejecutar el SQL y cerrarla. Como los cursores creo que tienen ambito a nivel de transacion, no es facil que coincidan dos cursores abiertos con el mismo nombre. |
#32
|
||||
|
||||
Creo que no estoy entendiendo algo.... no puede ser tan fácil, a ver, yo he hecho lo siguiente:
- en mdosql.pas he añadido una nueva propiedad pública al TMDOSQL:
y ahora en el Prepare:
FCursor es una variable protegida, ni propiedad ni nada, es una simple y mortar variable, pues la reuso y me quedo tan pancho. - Guardo y cierro todo. - Abro el paquete de los mdo que está en la carpeta "source" con nombre mdo_dX, pulso F12 para que aparezca la ventanita de compilación y pulso el botón compilar. - Listo, Ahora ya tengo una propiedad en el TMDOSQL que se llama "UniqueCursorName:string" que desde mi programa principal puedo asignar su valor. En el caso de que se te olvide asignar esa propiedad, en ejecución obtendrás una excepción muy bonita. Además no creo que se te olvide nunca... ¿qué es lo que me estoy perdiendo? PD: Si ahora me alguien con aquello de que esto es una chapuza más grande, pues que lo pinte de amarillito y con flores Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. Última edición por Lepe fecha: 14-12-2008 a las 23:46:56. |
#33
|
|||
|
|||
Sin haberlo probado, y arriesgo de equivocarme, ¿cual seria el cursor de las sentencias que acceden a las tablas del sistema? Creo que estaria vacio.
Y en los Dataset que tienen las 4 sentencias de SELECT, INSERT, UPDATE y DELETE?? Y en los script, backup, restore?? El problema es que name llega en blanco al crear el cursor, si llegase el nombre del query (dataset, script, ...) ya lo podriamos usar como identificador, y si le añadimos la hora, o la randomstring o las dos cosas ya tendriamos un identificador unico para cualquier SQL que pase por cualquier MDO. Yo no se como resolver lo del name, no tengo ni idea de porque no llega hasta el codigo donde se asigna al cursor. De momento, he dejado la linea del cursor asi: La rutina que ejecuta el randseed seguira puesta en el timer, reiniciandolo cada 5 minutos. En cuanto lo pruebe os comento. |
#34
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
¡Hola de nuevo!
Quisiera hacer algunas puntualizaciones. Cita:
Cita:
Entiendo el punto, y creo que aludes (corrígeme si no le atino) a esto mismo que Coso comentó después: Cita:
Claro está, no debemos usarla en casos donde necesitemos generar números únicos, porque, como ya hemos dicho, aleatorio no es lo mismo que único. De ahí mi sugerencia de usar otro método, pero aclarando que, por lo mismo, se nota que un hubo un intento (que pudo ser exitoso en su época) de añadir el nombre del objeto en la biblioteca de la cual derivaron los IBX y MDO. Cita:
Como dije anteriormente, no tiene sentido usar el valor de la propiedad Name si está vacía. Las interfaces IDesigner e IDesignerHook son "relativamente" recientes en Delphi, estoy seguro que no existían en las primeras versiones, y que ese método UniqueName de la segunda se implementaba de una forma más visible. Tengo la duda de si en aquel entonces, y sólo en tiempo de diseño, se daba el nombre predeterminado de los componentes desde el interior del constructor de TComponent, y no después de la construcción (algo en mi memoria trata de resurgir, pero lamentablemente no tengo Delphi 3, 4 o 5 conmigo para comprobarlo). Quizá ese método InsertComponent que vemos ahora ser llamado por el constructor, dentro de la unidad Classes.pas, era algo distinto. No puedo precisarlo sin una copia antigua de la VCL... Pero si así fuera, eso le daría justificación histórica al uso de Name dentro del constructor, pero, repito, sólo cuando tales objetos IBSQL o MDOSQL fuesen agregados a un contenedor en tiempo de diseño. Y, de lo contrario, nunca hubiese tenido sentido y se trataría de un error desde el comienzo de esos componentes. Cita:
Cita:
No sé qué tan culpables sean los autores por dejar un componente de software libre como está ahora y sugerirlo para versiones recientes, pero al menos yo veo un intento de mejorar el componente de parte de Marco De Groot. Y si bien este cambio ayuda poco en Delphi 7 (por las razones que comenté antes de los objetos MDOSQL internos), hubiera estado peor dejarlo como se encuentra ahora en los IBX. Vamos, creo que llevas algo de razón en lo que dices, pero me pareció oportuno señalar la precipitación que hubo en uno de tus comentarios, porque parecía que dabas por hecho la mala calidad de un software sin bases sólidas, sólo por lo desprendido hasta ese momento en el hilo, que, dicho sea de paso, derivó en una calificación un tanto injusta del comentario puesto por De Groot. Está claro que él u otra persona pudo implementar una mejor solución, como usar GUIDs o simplemente una variable global como contador, pero mover la sentencia al método Prepare fue mejor que dejarla como estaba, al menos para los componentes MDOSQL agregados en tiempo de diseño, no así con los que usan internamente los queries (a no ser que hubiera más cambios relacionados en los componentes durante estos últimos años, cosa que desconozco). Cita:
Cita:
Cita:
TMDOSQL es un derivado directo de TComponent, por lo que hereda de éste su propiedad Name. Los métodos de los que hemos estado hablando principalmente son de esa misma clase (TMDOSQL.Create, TMDOSQL.Prepare y TMDOSQL.ExecQuery). Es cuando agregas un componente TMDOSQL de la paleta de componentes cuando el diseñador de Delphi le dará un nombre predeterminado (y seguramente tú le darías alguno más apropiado con el inspector de objetos). Y, como expliqué anteriormente, parece ser que este es el único caso donde el cambio hecho por De Groot tiene un beneficio automático, debido a que este componente suele utilizarse más de manera interna, implícitamente, por parte de los componentes derivados de TMDOCustomDataSet: TMDODataSet, TMDOTable, TMDOQuery. Alguno de los cuales es el que seguramente estás utilizando. No es la propiedad Name del conjunto de datos (data set) de la que se ha hablado, sino de la propiedad Name de uno de esos componentes internos TMDOSQL que hay dentro del conjunto de datos. Mira esto:
Cita:
Pero si es un TMDOQuery o TMDOTable, tendrás que usar el clásico truco de molde de tipo (type cast) para acceder a la propiedad QSelect, ya que en estas dos clases la propiedad permanece en ámbito protegido (no está redeclarada en la sección Public como en TMDODataSet): Obviamente, esta acción debe ocurrir antes de que el método Prepare del objeto QSelect (TMDOSQL.Prepare) haga referencia a esa propiedad Name para formar el nombre del cursor. Cita:
Cita:
Cita:
Como podrás notar, esos cursores están creándose sin prefijo (su nombre será solamente la cadena de ocho dígitos aleatorios), debido a que el objeto de la variable Query recién creado no tiene valor en su propiedad Name. Cita:
Cierto, aunque recalco que la mejora no es muy grande que digamos, por las razones que ya expliqué. Bien recibida, eso sí. Cita:
No veo solución práctica por el lado de derivar clases de componentes, ya que la obtención del famoso número aleatorio no está dentro de algún bloque de código que sea fácilmente redefinible. Cita:
Cita:
Cita:
Cita:
Cita:
Cita:
Cita:
Suponiendo que alguno de los clientes de Sick Boy (¿cuál es tu nombre?) mantuviera la conexión indefinidamente, realizando cinco mil consultas por hora (10 veces más del volúmen bajo que mencionó), se necesitarían más de 98 años sin interrupción alguna del sistema para agotar el contador. Claro está, si bajo esas mismas circunstancias alguna otra computadora ejecutara, digamos, cincuenta mil consultas por hora, habrían de requerirse solamente 9.8 años, y como es muy probable que el programador siga vivo para entonces, lo mejor sería preverlo. Cita:
Cita:
Sobre esos componentes internos TMDOSQL tenemos menos control, especialmente con los creados temporalmente dentro métodos como InternalInitFieldDefs, InternalBatchOutput y DoOnNewRecord de la clase TMDOCustomDataSet (padre de TMDOQuery, TMDOTable y TMDODataSet). Continúo... Última edición por Al González fecha: 15-12-2008 a las 02:18:25. |
#35
|
||||
|
||||
Cita:
Si son objetos TMDOSQL que hacen Selects, pasará lo mismo. Cita:
Cita:
Insisto en que todavía cabe la posibilidad de estar haciendo alguna otra cosa mal, pero esperemos llegar a una solución óptima. Un abrazo puntualizado. Al González. Última edición por Al González fecha: 15-12-2008 a las 02:13:57. |
#36
|
||||
|
||||
Hola a todos,
Sobre como funcionan esos componentes no puedo opinar puesto que nunca los usé. Si uso IBX, en D6, con Firebird 1.5 y no tengo problemas con ellos (hasta el momento). Lo que me resulta extraño es lo que comentan sobre los números aleatorios, o mejor dicho pseudo-aleatorios. El problema con Random es que se lo limita a 8 caracteres, y la verdad es que al limitarlo es muy probable que consigamos números repetidos. He aquí la explicación: Internamente Random muy probablemente sea un generador lineal multiplicativo, al menos eso quisiera esperar (en la ayuda que acompaña a D6, no da información al respecto). Y si lo és, debería estar diseñado para responder del mejor modo a secuencias únicas. Al menos en teoría, se esperaría que los valores del generador sean los adecuados para garantizar que en toda la secuencia de M-1 números no exista un número repetido. Y este M es un valor bastante grande. Si en verdad es un GLM, y desean garantizar que el número obtenido sea "único" debería tomarse todos los decimales que éste devuelve. En realidad el generador devuelve números distribuidos uniformemente en el rango [0,1). Cuando uno llama a "RandomRange()" o a Random(Range) lo que se consigue es forzar el redondeo. Y por tanto se pierde esos valores únicos: los extensos decimales que hacen a cada número único e irrepetible en la secuencia. Si buscan sobre generadores de números pseudoaleatorios llegarán a hilos en donde hablé al respecto. De cualquier forma, si se quiere seguir dandole ideas de como obtener números únicos, y cuanto más grandes sean mejor, lo ideal es emplear ya sea int64 si se manejan con enteros o Extended si operan con los reales para que se puedan obtener números que no agotaríamos tan fácilmente. Y si se desea perfeccionar, aún más, siguiendo la idea de los números aleatorios. Lo más óptimo es tener múltiples generadores concatenados. Un ejemplo es así: numero = G1() + G2() + ... + Gn() El programa Arenna hace uso de esta técnicas para generar números enormes. Saludos, |
#37
|
|||
|
|||
Hola,
Al, muchas gracias por las molestias que te has tomado y las extensas respuestas (por cierto, mi nombre es Ricardo). Utilizo sobre todo TMDOQuery, muchos de ellos los creo y libero en tiempo de ejecucion. Tambien utilizo TMDODataset, aunque muchos menos. Si no entiendo mal, lo de una variable que se incremente seria algo como
Ahora una pregunta tonta, ¿donde declaro la variable miLong? En el private de TMDOSQL?? Y le pasamos el valor al cursor: Dejo Name porque no me molesta, y se puede utilizar sabiendo que el name corresponde a QSelect. Cita:
La rutina que esta en el timer realiza una encriptacion o desencriptacion de un string. aKey es la "clave" para obtener los resultados, asi que siempre es la misma, con lo que el generador de numeros aleatorios se reinicia siempre (por lo que he entendido) con la misma secuencia de numeros. A riesgo de parecer paranoico, si despues de utilizar estas funciones ejecuto un por ejemplo RandSeed(entero_no_repetido), donde "entero_no_repetido" haga honor a su nombre y sea distinto en cada ocasion. La verdad, creo que lo mejor puede ser la idea de que el cursor sea un "contador" y olvidarse para siempre del tema de los numeros aleatorios. Tener un error aleatorio que se propaga por todos los procedimientos de tu programa es una pesadilla. Si os preocupais por vuestros clientes y vuestro codigo no se lo deseo a nadie. Última edición por Sick boy fecha: 15-12-2008 a las 12:11:24. Razón: Editado: result:=inttostr(miLong); |
#38
|
|||
|
|||
yo abandono el hilo, creo que tienes herramientas suficientes y de sobras para solucionarlo facilmente. Tansolo estamos desgastando polemica y confusión insertada. saludos y suerte.
|
#39
|
|||
|
|||
Ok Coso, gracias por tu ayuda.
A falta de las pruebas, esto esta solucionado, acabo de poner lo que comentaba Al González y me ha parecido perfecto, elegante y simple. Siento la polemica sobre si los componentes son buenos, malos, bien escritos, etc.... Ojo, si piensas usar MDO, IBX y posiblemente FreeIB, deberias saber como los componentes generan el famoso cursor. De lo contrario, te puede pasar como a mi, y ante la falta de documentacion sobre el dichoso error 502, empiezas a probar soluciones de todo tipo sin encontrar el motivo de los errores. Al final, declare la variable en MDOUtils, como una variable global cualquiera, iniciandola con el valor minimo del tipo integer (si, decidi usar integer, me parece más que suficiente). En mi caso, el programa que hago no funciona ininterrupidamente, y cada vez que se reinicia el programa el contador empezara en el valor minimo de integer, y la verdad es que dudo de que en un solo dia consiga alcanzar los numeros positivos. Tengo clientes que hibernan el equipo (yo mismo lo hago), hay veces que el ventanucos aguanta hasta 30 dias sin fallar. Dudo de que en 30 ó 60 dias se acaben los valores de integer, en cualquier caso, si sucede se reinicia el contador. Al reiniciar el contador se podrian repetir los cursores de nuevo?? Claro, si empiezas otra vez se pueden repetir. En mi caso, un cursor nunca estará tanto tiempo activo (Al hablaba de años), asi que para mi es seguro. Sobre que se conecten otros equipos clientes y consuman mi contador, no creo que eso suceda. Evidentemente Al sabe más que yo, pero creo que en esto te equivocas, ya que el programa cliente que accede utilizará su propio contador, independiente en cada cliente. Y esto no nos importa porque los cursores deben de ser unicos en el ambito de la transaccion Si me equivoco en esto decirmelo. Quiero dejar el programa funcionando unos dias para ver que pasa, no quiero sorpresas, y despues postearé el codigo que he modificado, por si le sirve a alguen. Al menos ahora, no tengo que preocuparme de numeros aleatorios. Última edición por Sick boy fecha: 15-12-2008 a las 14:16:32. |
#40
|
||||
|
||||
Si Al González confía en los GUID, para mí sobran las palabras. ¿Qué tal esto?:
Esto iría en el constructor del TMDOSQL. Puesto que lo usan internamente para las tablas de sistema, ya estaríamos usando el famoso GUID (salvo error en mi código). Vaya, veo que Sick Boy ha implementado la solución, bueno, si falla, aquí tienes otra posibilidad. Edito: Al final esto no me gusta. La ayuda de delphi dice que puede saltar el EConverterror al traducirlo a string y en ese caso estaríamos de vuelta con el RandomString. Muy posiblemente la solución del Integer sea la mejor. Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. Última edición por Lepe fecha: 15-12-2008 a las 13:14:26. Razón: Resumen final |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Mensaje de error extraño | Sick boy | Firebird e Interbase | 0 | 12-12-2008 12:22:26 |
Error Extraño | SysAdminGCS | Varios | 1 | 18-08-2007 17:30:49 |
Error Extraño | Esau | SQL | 4 | 17-06-2005 23:44:16 |
error extraño | gilberto_1126 | Varios | 2 | 05-09-2004 02:01:01 |
Error Extraño | Esau | OOP | 5 | 19-11-2003 19:01:32 |
|