Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Novato en Firebird (https://www.clubdelphi.com/foros/showthread.php?t=76429)

salvica 31-10-2011 17:54:08

Novato en Firebird
 
Hola a todos.
Estoy haciendo una aplicación que debe funcionar en MySql / Firebird / SQLite3
mediante D-7, ZeosDBO 6.6.6 estable y Firebird Server 2.5.1

Intento hacer ésta consulta para Firebird
Código SQL [-]
SELECT COUNT(*) AS existe
  FROM rdb$relations
 WHERE rdb$relation_name = 'MITABLA'
   AND rdb$view_blr is null
   AND (rdb$system_flag is null OR rdb$system_flag=0);
y obtengo éste error:
raised exception class EAccessViolation with message 'Access violation at address 00000000'.

La dichosa consulta debe devolver la existencia de una tabla (es este caso MITABLA) y la creo con esta función:
Código Delphi [-]
  function  FIREBIRD_ExisteTabla( ZQuery:TZQuery; TableName:string;
                                  PathSqlError:string ):boolean;
  begin
    Result := false;
    with ZQuery do begin
         Active := false;
         SQL.Clear;
         SQL.Add( 'SELECT COUNT(*) AS existe' );
         SQL.Add( '  FROM rdb$relations' );
         SQL.Add( ' WHERE rdb$relation_name = '''+UpperCase(TableName)+'''' );
         SQL.Add( '   AND rdb$view_blr is null' );
         SQL.Add( '   AND (rdb$system_flag is null OR rdb$system_flag=0);'  );
         try
           Open; <------ AQUÍ "CASCA" :mad:
           Result := ( FieldByName('EXISTE').AsInteger>0 );
         { cerrar la ZQuery }
           Close;
         except
           SQL.SaveToFile( PathSqlError+'\ERROR_FIREBIRD_ExisteTabla_'+TableName+'.sql' );
         end;
    end; { del with ZQuery do }
  end;
¿Podeis decirme qué estoy haciendo mal?
La consulta es adaptada de esta que encontré en internet.

Gracias de antemano
salvica

defcon1_es 31-10-2011 19:04:39

Hola.

Si has probado a ejecutar la select desde IBExpert, IBConsole o similar y no te ha dado problemas,
yo probaría a usar QuotedStr(), por si fuese problema de las comillas.

Código Delphi [-]
SQL.Add( ' WHERE rdb$relation_name = '+QuotedStr(UpperCase(TableName)));

PD: Mejor pásalo como parámetro
Código Delphi [-]
SQL.Add( ' WHERE rdb$relation_name = :Mitabla ');
...
...
ParamByName('Mitabla').AsString := Tablename;
Open;

salvica 31-10-2011 19:47:43

Hola defcon1_es, gracias por responder.

Lo he cambiado a parámetros y sigue dando el mismo error. :mad::mad::mad:

La consulta la ejecuto en el FlameRobin y funciona correctamente, no sé lo que demonios puede ocurrir.

Saludos
salvica

RONPABLO 31-10-2011 20:41:13

El problema con el EAccesViolation es que es muy poco dicientes, lo que se me viene a la mente es que el problema no es de la consulta como tal, más bien diría que es del componente, o del valor que se esta enviando en TableName, busca una herramienta de debugger (algo así como el eurekaLog) ese puede dar mejores datos que el simple EAccesViolation

salvica 31-10-2011 21:09:26

Hola RONPABLO, buenas noches.

Antes de abrir la consulta, (para comprobar), la salvo en un fichero:
Código SQL [-]
SQL.SaveToFile( PathSqlError+'\FIREBIRD_ExisteTabla_'+TableName+'.sql' );
try
  Open;
except
  SQL.SaveToFile( PathSqlError+'\ERROR_FIREBIRD_ExisteTabla_'+TableName+'.sql' );
end;
y el resultado es la misma que pongo al principio
Código SQL [-]
SELECT COUNT(*) AS existe
  FROM rdb$relations
 WHERE rdb$relation_name = 'MITABLA'
   AND rdb$view_blr is null
   AND (rdb$system_flag is null OR rdb$system_flag=0);
Esta misma consulta (con las adaptaciones correspondientes), la tengo para MySql y para SQLite3.

El error en sí no dice nada, pero si corro la consulta sobre FlameRobin o sobre SQL Maestro funciona correctamente, así que supongo que el error es de Firebird.

Si en la consulta cambio "MITABLA" por "mitabla", me devuelve CERO (no existe)

Por cierto, ya que estamos :D:D:D
¿Sabes como se configura el servidor para que admita mayúsculas y minúsculas en lo nombres de campo?
Cuando yo creo las tablas, los nombres de tabla los pongo en minúsculas y los nombres de campo en mayúsculas (cosas de la edad :p), pero Firebird 2.5 lo cambia TODO a mayúsculas.

Gracias por lo que puedas ayudarme y perdona por el "rollo" que te he metido, pero estoy hasta los c****es de los diferentes formatos de SQL

Saludos
salvica

ecfisa 31-10-2011 21:44:19

Hola salvica.

Cita:

El error en sí no dice nada, pero si corro la consulta sobre FlameRobin o sobre SQL Maestro funciona correctamente, así que supongo que el error es de Firebird.
No uso Zeos por lo que no tengo manera de probarlo, pero creo que el error es debido al componente TZQuery y no a Firebird, ya que hice una prueba usando TIBQuery y me funciona correctamente:
Código Delphi [-]
function TForm1.ExisteTabla(Nombre: string): boolean;
begin
  with TIBQuery.Create(nil) do
  try
    Database:= IBDatabase1;
    SQL.Clear;
    SQL.Add('SELECT COUNT(*) AS FOUND');
    SQL.Add('FROM RDB$RELATIONS');
    SQL.Add('WHERE RDB$RELATION_NAME = :TABLA AND RDB$VIEW_BLR IS NULL');
    SQL.Add('AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)');
    ParamByName('TABLA').AsString:= Nombre;
    Open;
    Result:= FieldByName('FOUND').AsInteger > 0;
    Close;
  finally
    Free;
  end;
end;

Un saludo.

salvica 31-10-2011 21:54:53

Cita:

Empezado por ecfisa (Mensaje 417224)
Hola salvica.

No uso Zeos por lo que no tengo manera de probarlo, pero creo que el error es debido al componente TZQuery y no a Firebird, ya que hice una prueba usando TIBQuery y me funciona correctamente:
Un saludo.

Hola ecfisa, buenas noches.

Indagaré, a ver si tengo algo mal en el ZConnection por si acaso, pero ya te adelanto que si no compruebo la existencia de la tabla, el mismo ZQuery crea la tabla sin problemas.

Saludos
salvica

RONPABLO 31-10-2011 22:02:25

Esa consulta la corro directamente sobre firebird y funciona bien osea que error de firebird no es, y con el resultado que envía se nota que el valor de "TableName" llega bien, por lo cual yo me centraría en buscr el error por los componentes ZeoMDO, de pronto hace alguna validación en la estructura del query y no soporta hacer consultas en tablas del sistema en firebird... Por curiosidad, la consulta:

Código SQL [-]
SELECT COUNT(*) AS existe   
FROM rdb$relations  WHERE rdb$relation_name = 'MITABLA'    
AND rdb$view_blr is null    
AND (rdb$system_flag is null OR rdb$system_flag=0);

Prueba a quitar el ";" del final, el componente no debe de necesitarlo al final y de pronto saca erro por tenerlo..




Respecto a usar Nombres de campos o de tablas en mayúsculas o minúsculas puede hacerlo desde comandos encerrando el nombre de la tabla o el campo entre comilla doble, aunque es muy dispendioso hacerlo así ya que de ahí en adeltante deberá hacer las consultas de esa misma forma. ejemplo:


Código SQL [-]
Create Table "Tabla1"....
....
....
select "Campo1" from "Tabla1"

salvica 31-10-2011 22:28:53

Hola RONPABLO
Cita:

Empezado por RONPABLO (Mensaje 417228)
Esa consulta la corro directamente sobre firebird y funciona bien osea que error de firebird no es, y con el resultado que envía se nota que el valor de "TableName" llega bien, por lo cual yo me centraría en buscr el error por los componentes ZeoMDO, de pronto hace alguna validación en la estructura del query y no soporta hacer consultas en tablas del sistema en firebird... Por curiosidad, la consulta:

Ya te digo que la consulta la he probado sobre FlameRobin y funciona correctamente.

Cita:

Empezado por RONPABLO (Mensaje 417228)
Prueba a quitar el ";" del final, el componente no debe de necesitarlo al final y de pronto saca erro por tenerlo..

Le he quitado el punto y coma y hace lo mismo.
El punto y coma al final de la instrucción es para eso mismo, para decir que es el final y que lo ejecute, después pueden ir más sentencias sql.

Cita:

Empezado por RONPABLO (Mensaje 417228)
Respecto a usar Nombres de campos o de tablas en mayúsculas o minúsculas puede hacerlo desde comandos encerrando el nombre de la tabla o el campo entre comilla doble, aunque es muy dispendioso hacerlo así ya que de ahí en adeltante deberá hacer las consultas de esa misma forma. ejemplo:

No, si lo que quiero es escribir los nombres de tabla en minúsculas y que me los reconozca. Vamos para no tener que ir metiendo UpperCase() por todo el código.

Esto funciona con MySql, SQLite, Oracle (vamos con todos, menos con mi Firebird)

Saludos
salvica

RONPABLO 31-10-2011 23:03:11

Por ejemplo la siguiente consulta traería el resultado sin necesidad de hacer el upperCase, el problema, radica en que si existe una tabla llamada "MiTala" y otra llamada "MiTalaPersonal" encuentra las dos.
Código SQL [-]
SELECT COUNT(*) AS existe
  FROM rdb$relations
 WHERE rdb$relation_name CONTAINING  'MiTabla'
   AND rdb$view_blr is null
   AND (rdb$system_flag is null OR rdb$system_flag=0)

RONPABLO 31-10-2011 23:07:40

Cita:

Empezado por salvica (Mensaje 417231)


No, si lo que quiero es escribir los nombres de tabla en minúsculas y que me los reconozca. Vamos para no tener que ir metiendo UpperCase() por todo el código.

Esto funciona con MySql, SQLite, Oracle (vamos con todos, menos con mi Firebird)
Saludos
salvica


Ahora con lo de ir metiendo UpperCase me queda una duda:


Código SQL [-]
Select * from MITABLA

y

Código SQL [-]
Select * from MiTabla

Alguno de las dos consultas pone algún problema? o el problema es cuando hace la consulta a la tabla del sistema y compara los nombres de los campos allá y todos los encuentra en mayúsculas?

salvica 31-10-2011 23:46:46

Hola de nuevo RONPABLO, te estoy dando la noche :p

Son dos cosas diferentes:
  • El error de excepción: Me lo dá cuando hago el Open en la ZQuery de ZeosDBO.
Si elimino a "mano" la tabla y en el código del programa quito la línea que comprueba la existencia de la tabla, el mismo ZQuery efectúa un CREATE TABLE mitabla sin problemas, con lo que (inicialmente), la conexión es correcta, el enlace del ZQuery con el ZConnection es correcto y el ZQuery trabaja como se espera.
  • Lo de las mayúsculas: Otro cantar, que no sé si es por el manejador FlameRobin que viene con Firebird o qué.
Por ejemplo, yo creo una tabla:
Código SQL [-]
    with ZQuery do begin
         SQL.Clear;
         SQL.Add( 'CREATE TABLE mitabla (' );
         SQL.Add( '       NUM_REG     INTEGER        NOT NULL,' );
         SQL.Add( '       ID_CLAVE    CHAR(8)        NOT NULL,' );
         SQL.Add( '       CORRECTO    CHAR(1)        DEFAULT ''0'' NOT NULL,' );
         SQL.Add( '       TEXTO       VARCHAR(80)'    );
         SQL.Add( ');' );
         SQL.SaveToFile( PathSql+'\SQL_CrearTabla_mitabla.sql');
         try
           ExecSQL;
         except
           SQL.SaveToFile( PathSql+'\ERROR_SQL_CrearTabla_mitabla.sql');
         end;
         Close; { cerrar la tabla por si queda abierta }
    end; { del with ZQuery do }

Esto funciona sin problemas :D, ahora voy al FlameRobin (gratis) o al SQL Maestro for Firebird (de pago, pero bastante bueno, yo lo uso con SQLite) y ejecuto la consulta
Código SQL [-]
SELECT COUNT(*) AS existe
  FROM rdb$relations
 WHERE rdb$relation_name = 'MITABLA'
El campo EXISTE vale UNO (1), ha encontrado la tabla creada.

Si cambio la consulta por:
Código SQL [-]
 SELECT COUNT(*) AS existe
   FROM rdb$relations
  WHERE rdb$relation_name = 'mitabla'
El campo EXISTE vale CERO (0), no ha encontrado la tabla creada.
Esto si que es un "rollo"

Saludos
salvica

Casimiro Notevi 01-11-2011 00:21:13

Si das de alta (creas) una tabla, campos, store procedure, etc. SIN poner comillas, entonces lo podrás usar escribiéndolo como quieras, mayúsculas o minúsculas.
Pero si lo das de alta CON comillas, entonces luego tienes que llamarlo exactamente igual a como lo diste de alta.
Resumiendo:
caso 1:
create tabla TABLA
es lo mismo que
create tabla tabla

pero:
caso 2:
create tabla 'TABLA'
es distinto a
create tabla 'tabla'

En el caso 1, podrás usar: select TABLA, select tabla, select TaBlA, select tAbLa, etc.
en el caso 2, sólo podrás usar 'TABLA'.

Por ese motivo yo siempre doy de alta (lo creo) todo sin comillas. Como el primer caso.

ecfisa 01-11-2011 00:24:53

Cita:

Empezado por salvica (Mensaje 417226)
Hola ecfisa, buenas noches.

Indagaré, a ver si tengo algo mal en el ZConnection por si acaso, pero ya te adelanto que si no compruebo la existencia de la tabla, el mismo ZQuery crea la tabla sin problemas.

Hola salvica.

Es que tampoco creo que sea un error de creación, me inclino más por pensar que el componente no soporta esa consulta... ¿ Hiciste la prueba con un TIBQuery ?

Un saludo.

RONPABLO 01-11-2011 06:51:01

Cita:

Empezado por salvica (Mensaje 417239)
Hola de nuevo RONPABLO, te estoy dando la noche :p

Son dos cosas diferentes:
  • El error de excepción: Me lo dá cuando hago el Open en la ZQuery de ZeosDBO.
Si elimino a "mano" la tabla y en el código del programa quito la línea que comprueba la existencia de la tabla, el mismo ZQuery efectúa un CREATE TABLE mitabla sin problemas, con lo que (inicialmente), la conexión es correcta, el enlace del ZQuery con el ZConnection es correcto y el ZQuery trabaja como se espera.


Has mirado si hay una versión más nueva de los componentes, puede que con actualizarlos se arreglen.


Cita:

Empezado por salvica (Mensaje 417239)

Lo de las mayúsculas: Otro cantar, que no sé si es por el manejador FlameRobin que viene con Firebird o qué.
Por ejemplo, yo creo una tabla:
Código SQL [-] with ZQuery do begin SQL.Clear; SQL.Add( 'CREATE TABLE mitabla (' ); SQL.Add( ' NUM_REG INTEGER NOT NULL,' ); SQL.Add( ' ID_CLAVE CHAR(8) NOT NULL,' ); SQL.Add( ' CORRECTO CHAR(1) DEFAULT ''0'' NOT NULL,' ); SQL.Add( ' TEXTO VARCHAR(80)' ); SQL.Add( ');' ); SQL.SaveToFile( PathSql+'\SQL_CrearTabla_mitabla.sql'); try ExecSQL; except SQL.SaveToFile( PathSql+'\ERROR_SQL_CrearTabla_mitabla.sql'); end; Close; { cerrar la tabla por si queda abierta } end; { del with ZQuery do }


Esto funciona sin problemas :D, ahora voy al FlameRobin (gratis) o al SQL Maestro for Firebird (de pago, pero bastante bueno, yo lo uso con SQLite) y ejecuto la consulta
Código SQL [-]SELECT COUNT(*) AS existe FROM rdb$relations WHERE rdb$relation_name = 'MITABLA'

El campo EXISTE vale UNO (1), ha encontrado la tabla creada.

Si cambio la consulta por:
Código SQL [-] SELECT COUNT(*) AS existe FROM rdb$relations WHERE rdb$relation_name = 'mitabla'

El campo EXISTE vale CERO (0), no ha encontrado la tabla creada.
Esto si que es un "rollo"

Saludos
salvica

Es curioso, para mi ese es el funcionamiento que debe de tener una consulta, el identificar la diferencia entre mayúsculas y minúsculas es lo que me espero en un "Where Campo = 'Valor', ahora si la consulta solo la construye una sola vez y la llama muchas veces mandando el nombre de la tabla como parametro entoces podría hacer el Upper en la consulta y no en el código Delphi y así no se va a llenar de UpperCase, ya si la consulta la construye siempre pues esto sería casi igual.

salvica 01-11-2011 15:27:10

Doy por cerrado el tema
 
Agradezco a todos la ayuda y sus experiencias

Me disteis una buena pista cuando pusiste en duda la compatibilidad de ZeosDBO con Firebird 2.5

En este post y en este otro, comentaban que el sistema les daba la dichosa excepción al hacer Open en un select normalito, y que lo habian solucionado reinstalando Firebird a su versión 2.1.

¡¡¡ Efectivamente !!!

Me habia leido casi todos los post que hablaban de ZQuery+firebird en ésta plataforma y no había sido capaz de verlo

Gracias a San Google y buscando por "TZQuery Access violation at address 00000000. Read of address 00000000" me trajo a los enlaces arriba señalados.

Gracias de nuevo a todos

salvica

Delphius 02-11-2011 05:02:58

El problema con las diferencias entre mayúsculas y minúsculas se debe a que IBExpert permite establecer si se desea que los objetos se escriban siempre en mayúsculas o no. Cuando creas y registras una tabla hay un checkbox que dice algo "Upercase all objects" o parecido.
Si desactivas esta opción (por defecto está activada) conseguirás que tu tablas, campos, consultas, etc... todo lo que escribas respete y distinga mayúsculas de minúsculas. Y no termina allí la historia sino que además te ves obligado a hacer uso de comillas dobles.

Aunque esto no es en realidad algo de IBExperts, es una configuración de Firebird. Aunque no recuerdo cuál.

El estándar SQL sugiere que SIEMPRE se escriba todo en MAYÚSCULAS, pero se deja al usuario la posibilidad de alterar este comportamiento si así lo considera oportuno.

A mi en lo personal me resulta desagradable leer todo en mayúsculas, parece que me estuviera gritando. Pero tampoco me agrada tener que estar utilizando comillas dobles.

Saludos,

salvica 03-11-2011 19:22:56

Cita:

Empezado por Delphius (Mensaje 417347)
El problema con las diferencias entre mayúsculas y minúsculas se debe a que IBExpert permite establecer si se desea que los objetos se escriban siempre en mayúsculas o no. Cuando creas y registras una tabla hay un checkbox que dice algo "Upercase all objects" o parecido.
Si desactivas esta opción (por defecto está activada) conseguirás que tu tablas, campos, consultas, etc... todo lo que escribas respete y distinga mayúsculas de minúsculas. Y no termina allí la historia sino que además te ves obligado a hacer uso de comillas dobles.
Saludos,

Hola Delphius

El problema real era que (no se por qué) me "obligaba" a introducir los nombres de tabla y los nombres de campo en mayúsculas.

El contenido de los campos fué culpa mia, ya que creé la tabla con el collate ES_ES y lo tenía que haber creado con ES_ES_CI_CA (creo, que hora no tengo el manual) para ser insensible a mays. mins.

Ahora he bajado a la versión 2.1.4 (para poder seguir utilizando ZeosDBO).

Como tengo que hacer otra aplicación (leer ficheros csv), la haré con los IB (que dicen que son más rápidos)

Saludos
salvica


La franja horaria es GMT +2. Ahora son las 16:30:56.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi