Ir al contenido


Foto

Listando los campos de una tabla de Firebird se repite varias veces


  • Por favor identifícate para responder
4 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 01 junio 2016 - 05:58

Utilizo fireDAC en Delphi XE7, tengo una consulta que devuelve los campos y su tipo de datos de una tabla Firebird 2.5, en ibExpert los datos se muestran correctamente, en el Query Editor del componente FDQuery también me muestra los datos correctamente, pero al ejecutar la consulta en tiempo de ejecución me muestra registros repetidos (Y muchos!), les dejo la consulta y el resultado:


sql
  1. SELECT DISTINCT r.RDB$FIELD_NAME AS field_name,
  2. r.RDB$DESCRIPTION AS field_description,
  3. r.RDB$DEFAULT_VALUE AS field_default_value,
  4. r.RDB$NULL_FLAG AS field_not_null_constraint,
  5. f.RDB$FIELD_LENGTH AS field_length,
  6. f.RDB$FIELD_PRECISION AS field_precision,
  7. f.RDB$FIELD_SCALE AS field_scale,
  8. CASE f.RDB$FIELD_TYPE
  9. WHEN 261 THEN 'BLOB'
  10. WHEN 14 THEN 'CHAR'
  11. WHEN 40 THEN 'CSTRING'
  12. WHEN 11 THEN 'DECIMAL'
  13. WHEN 27 THEN 'DOUBLE PRECISION'
  14. WHEN 10 THEN 'FLOAT'
  15. WHEN 16 THEN 'INT64'
  16. WHEN 8 THEN 'INTEGER'
  17. WHEN 9 THEN 'QUAD'
  18. WHEN 7 THEN 'SMALLINT'
  19. WHEN 12 THEN 'DATE'
  20. WHEN 13 THEN 'TIME'
  21. WHEN 35 THEN 'TIMESTAMP'
  22. WHEN 37 THEN 'VARCHAR'
  23. ELSE 'UNKNOWN'
  24. END AS field_type,
  25. f.RDB$FIELD_SUB_TYPE AS field_subtype,
  26. coll.RDB$COLLATION_NAME AS field_collation,
  27. cset.RDB$CHARACTER_SET_NAME AS field_charset
  28. FROM RDB$RELATION_FIELDS r
  29. LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME
  30. LEFT JOIN RDB$COLLATIONS coll ON r.RDB$COLLATION_ID = coll.RDB$COLLATION_ID
  31. LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID =
  32. cset.RDB$CHARACTER_SET_ID
  33. WHERE r.RDB$RELATION_NAME = :TABLA
  34. ORDER BY r.RDB$FIELD_POSITION;

Archivo adjunto  campos.png   10,13KB   2 descargas

 

¿Alguien me podrá explicar cual es el problema?


  • 0

#2 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 01 junio 2016 - 06:56

A mi me pasa lo mismo, este es el resultado de tu query en una tabla firebird 2.5:

 

7436af6adc208d9e4a7e1fddbb268eb1o.jpg

 

 

El resultado es el mismo desde un query Delphi y desde IBExpert

 

Al parecer los duplicados son por el collate de los campos varchar

 

Esta es mi tabla:


delphi
  1. CREATE TABLE Asistencia (
  2. Id BIGINT NOT NULL PRIMARY KEY,
  3. IdSocio INTEGER NOT NULL,
  4. Anulada SMALLINT NOT NULL,
  5. Comentario VARCHAR(100) NOT NULL,
  6. Tipo INTEGER NOT NULL,
  7. Fecha DATE NOT NULL,
  8. Hora TIME NOT NULL)


  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 01 junio 2016 - 07:17

No he hecho otra prueba puesto que esto parece estar ya demostrado. Yo generalizaría la expresión, y me animaría a decir, que afectaría a todo lo que sea sensible de tener un collate. Recuerden que no sólo existe el VARCHAR, está también el CHAR y hay un sub tipo de blob diseñado para texto.

 

Por defecto Firebird establece el valor NONE tanto como charset como collate. Básicamente el NONE le dice al motor que reciba las cosas como vengan y no intente ningún encoding. Quizá justamente como no tiene un collate definido aplica a todo, y de allí que para dicho campo le sea permitido todos los collate que incorpora y soporta Firebird.

Lo que podrían comprobar es si definiendo un collate y/o charset al campo en cuestión sigue repitiendo el proceso.

 

Saludos,


  • 1

#4 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 02 junio 2016 - 07:24

Están en lo cierto, el problema es los collate, el left join no responde como debe porque la estructura de la tabla esta diseñado de otra forma, o sea, el campo RDB$COLLATION_ID repite un mismo id, eso es debido a que depende del RDB$CHARACTER_SET_ID, dejo una imagen para mejor entendimiento:

 

Archivo adjunto  collate.png   212,11KB   1 descargas

 

veré cómo hago la relación entre RDB$COLLATION y RDB$CHARACTER_SET

 

Saludos.


  • 0

#5 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 02 junio 2016 - 07:42

Encontré ésta versión en StackOverflow y funciona de maravillas;


sql
  1. SELECT
  2. RF.RDB$FIELD_NAME FIELD_NAME,
  3. CASE F.RDB$FIELD_TYPE
  4. WHEN 7 THEN
  5. CASE F.RDB$FIELD_SUB_TYPE
  6. WHEN 0 THEN 'SMALLINT'
  7. WHEN 1 THEN 'NUMERIC(' || F.RDB$FIELD_PRECISION || ', ' || (-F.RDB$FIELD_SCALE) || ')'
  8. WHEN 2 THEN 'DECIMAL'
  9. END
  10. WHEN 8 THEN
  11. CASE F.RDB$FIELD_SUB_TYPE
  12. WHEN 0 THEN 'INTEGER'
  13. WHEN 1 THEN 'NUMERIC(' || F.RDB$FIELD_PRECISION || ', ' || (-F.RDB$FIELD_SCALE) || ')'
  14. WHEN 2 THEN 'DECIMAL'
  15. END
  16. WHEN 9 THEN 'QUAD'
  17. WHEN 10 THEN 'FLOAT'
  18. WHEN 12 THEN 'DATE'
  19. WHEN 13 THEN 'TIME'
  20. WHEN 14 THEN 'CHAR(' || (TRUNC(F.RDB$FIELD_LENGTH / CH.RDB$BYTES_PER_CHARACTER)) || ') '
  21. WHEN 16 THEN
  22. CASE F.RDB$FIELD_SUB_TYPE
  23. WHEN 0 THEN 'BIGINT'
  24. WHEN 1 THEN 'NUMERIC(' || F.RDB$FIELD_PRECISION || ', ' || (-F.RDB$FIELD_SCALE) || ')'
  25. WHEN 2 THEN 'DECIMAL'
  26. END
  27. WHEN 27 THEN 'DOUBLE'
  28. WHEN 35 THEN 'TIMESTAMP'
  29. WHEN 37 THEN 'VARCHAR(' || (TRUNC(F.RDB$FIELD_LENGTH / CH.RDB$BYTES_PER_CHARACTER)) || ')'
  30. WHEN 40 THEN 'CSTRING' || (TRUNC(F.RDB$FIELD_LENGTH / CH.RDB$BYTES_PER_CHARACTER)) || ')'
  31. WHEN 45 THEN 'BLOB_ID'
  32. WHEN 261 THEN 'BLOB SUB_TYPE ' || F.RDB$FIELD_SUB_TYPE
  33. ELSE 'RDB$FIELD_TYPE: ' || F.RDB$FIELD_TYPE || '?'
  34. END FIELD_TYPE,
  35. IIF(COALESCE(RF.RDB$NULL_FLAG, 0) = 0, NULL, 'NOT NULL') FIELD_NULL,
  36. CH.RDB$CHARACTER_SET_NAME FIELD_CHARSET,
  37. DCO.RDB$COLLATION_NAME FIELD_COLLATION,
  38. COALESCE(RF.RDB$DEFAULT_SOURCE, F.RDB$DEFAULT_SOURCE) FIELD_DEFAULT,
  39. F.RDB$VALIDATION_SOURCE FIELD_CHECK,
  40. RF.RDB$DESCRIPTION FIELD_DESCRIPTION
  41. FROM RDB$RELATION_FIELDS RF
  42. JOIN RDB$FIELDS F ON (F.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE)
  43. LEFT OUTER JOIN RDB$CHARACTER_SETS CH ON (CH.RDB$CHARACTER_SET_ID = F.RDB$CHARACTER_SET_ID)
  44. LEFT OUTER JOIN RDB$COLLATIONS DCO ON ((DCO.RDB$COLLATION_ID = F.RDB$COLLATION_ID) AND (DCO.RDB$CHARACTER_SET_ID = F.RDB$CHARACTER_SET_ID))
  45. WHERE (RF.RDB$RELATION_NAME = :TABLA) AND (COALESCE(RF.RDB$SYSTEM_FLAG, 0) = 0)
  46. ORDER BY RF.RDB$FIELD_POSITION;

Un poco largo sí, sólo me faltaría agregarle los campos que faltan.

 

Saludos.


  • 2




IP.Board spam blocked by CleanTalk.