Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird Feldtypen richtig benennen (https://www.delphipraxis.net/136843-firebird-feldtypen-richtig-benennen.html)

Morphie 8. Jul 2009 21:33

Datenbank: Firebird • Zugriff über: IBDAC

Firebird Feldtypen richtig benennen
 
Nabend liebe DPler!

Ich möchte gerne eine Datenbank-Update-Funktion in mein Programm einbauen, so, dass ich die META-Daten (Tabellennamen, Feldnamen, Feldtypen, max. längen usw.) aus MEINER Datenbank auslese, in eine bestimmte Datei abspeichere, die die Datei dann weitergeben kann.
Beim Anwender soll das Programm dann die META-Daten mit der Datenbank des Anwenders vergleichen und ggf. die Datenbank anpassen. (neue Tabellen anlegen, Felder ändern, neue Felder anlegen, Felder löschen etc.)

Jetzt zur Frage: Wie kann ich die META-Daten sauber auslesen?
im Moment bin ich auf dieses hier gestoßen:
SQL-Code:
SELECT r.RDB$FIELD_NAME AS field_name,    
r.RDB$RELATION_NAME AS tablename,      
r.RDB$DEFAULT_VALUE AS field_default_value,        
r.RDB$NULL_FLAG AS field_not_null_constraint,        
f.RDB$FIELD_LENGTH AS field_length,            
t.RDB$TYPE_NAME as field_type  
FROM RDB$RELATION_FIELDS r  
LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME
LEFT JOIN RDB$TYPES t on f.RDB$FIELD_TYPE = t.RDB$TYPE
LEFT JOIN RDB$COLLATIONS coll ON f.RDB$COLLATION_ID = coll.RDB$COLLATION_ID
LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID = cset.RDB$CHARACTER_SET_ID
WHERE r.RDB$SYSTEM_FLAG=0
AND t.RDB$FIELD_NAME = 'RDB$FIELD_TYPE'
ORDER BY r.RDB$FIELD_POSITION;
ergibt folgendes Ergebnis:
Code:
FIELD_NAME   TABLENAM   FIELD_DEFAULT_VALUE   FIELD_NOT_NULL_CONSTRAINT   FIELD_LENGTH   FIELD_TYPE
TABELLE      TABELLEN   NULL                                          1             255    VARYING
FELD         TABELLEN   NULL                                                        255    VARYING
TYP          TABELLEN   NULL                                                        255    VARYING
LAENGE       TABELLEN   NULL                                                          4    LONG
OPTIONEN     TABELLEN   NULL                                                        255    VARYING
Die Feldtypen machen mir nun ein bisschen Probleme... Eigentlich sind die Felder als VARCHAR(255) deklariert, was intern anscheinend als VARYING verarbeitet wird. Gibt es eine saubere Möglichkeit, diese Feld_typen nun SQL-Komform zu benennen? Schließlich erstelle ich die Tabelle ja so:
SQL-Code:
CREATE TABLE TABELLEN (
  TABELLE  VARCHAR(255) NOT NULL,
  FELD     VARCHAR(255),
  TYP      VARCHAR(255),
  LAENGE   INTEGER,
  OPTIONEN VARCHAR(255)
);
Hoffe ihr versteht mein Problem...
Vielen Dank im Voraus

Morphie 10. Jul 2009 11:50

Re: Firebird Feldtypen richtig benennen
 
*push*

borwin 10. Jul 2009 12:47

Re: Firebird Feldtypen richtig benennen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hoffe ich habe Dein Problem verstanden.
In den Systemtabellen stehen für die Feldtypen die Nummern (rdb$fields.rdb$field_type).
Brauchst Du jetzt die Namen dazu, mußt Du die Zahlen umschlüsseln. Habe Dir mal ein Bild angehangen mit den Datentypen.
Das 'NEW_' weglassen. Auch die Subtypen beachten.

Gruß Borwin

Jürgen Thomas 10. Jul 2009 12:58

Re: Firebird Feldtypen richtig benennen
 
Hallo,

ich hatte seinerzeit ein ähnliches Problem. Ich habe das mit einer StoredProcedure gelöst:
SQL-Code:
CREATE OR ALTER PROCEDURE GET_DATENTYP (
    Typ SMALLINT,
    Sub SMALLINT,
    Len SMALLINT,
    Prec SMALLINT,
    Scale SMALLINT,
    Text CHAR(67))
RETURNS (
    Data VARCHAR(20))
AS
begin
  /* Procedure Text */

  if ((Typ = 10) or (Typ = 12) or (Typ = 13) or (Typ = 27) or (Typ = 35)) then
  begin
    /*  einfache Konvertierungen */
    /*  gegebener Text wird unveraendert uebernommen */
    if (StrLen(Text) > 20) then
      Text = Substr(Text,1,20);
    Data = Trim(Text);
  end
  else begin
    if ((Typ = 7) or (Typ = 8) or (Typ = 16)) then
    begin
      /* numerische Typen: Wertebereich, Laenge, Praezision */
      if (Sub = 0) then
      begin
        if (Typ = 7) then
          Data = 'SMALLINT';
        else
          if (Typ = 8) then
            Data = 'INTEGER';
          else
            Data = 'BIGINT';
      end
      else begin
        if (Sub = 1) then
          Data = 'NUMERIC(' || prec || ',' || (0 - scale) || ')';
        else
          Data = 'DECIMAL(' || prec || ',' || (0 - scale) || ')';
      end
    end
    else begin
      if (Typ = 261) then
      begin
        /* Blobs */
        if (Sub = 0) then
          Data = 'BLOB / BINARY';
        else
          Data = 'BLOB / TEXT';
      end
      else begin
        if ((Typ = 14) or (Typ = 37)) then
        begin
          /* char und varchar */
          if (Typ = 14) then
            Data = 'CHAR(' || len || ')';
          else
            Data = 'VARCHAR(' || len || ')';
        end
        else Data = 'UNKNOWN';
      end
    end
  end
  suspend;
end
Als Parameter werden übergeben:
Code:
RDB$Fields.RDB$Field_Type, RDB$Fields.RDB$Field_Sub_Type,
RDB$Fields.RDB$Field_Length, RDB$Fields.RDB$Field_Precision,
RDB$Fields.RDB$Field_Scale, RDB$Types.RDB$Type_Name
Vielleicht kannst du damit etwas anfangen. Jürgen

PS. Ich musste danach in meinen Quellen erst suchen, sonst hätte ich früher geantwortet.

Morphie 10. Jul 2009 13:06

Re: Firebird Feldtypen richtig benennen
 
Vielen Dank an euch beiden, das hilft mir schon mal ziemlich weiter :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz