Entwickler-Ecke

Datenbanken - Suche diese SQL-Befehle für Firebird Datenbanksysteme


e86 - Di 03.01.06 14:02
Titel: Suche diese SQL-Befehle für Firebird Datenbanksysteme
Hallo,

ich suche für das Firebird-Datenbanksystem folgende SQL-Befehle, die mir folgendes bewirken:

- Das Zurückgeben von allen Tabellennamen einer bestimmten Datenbank
- Das Zurückgeben aller Eigenschaften der Tabellen einer Datenbank ODER das Zurückgeben aller Eigenschaften aller Tabellen einer Datenbank
- Das Zurückgeben der Eigenschaften von den Spalten einer bestimmten Tabelle


Dies benötige ich in Verbindung mit .NET, was hier aber ersteinmal nicht wichtig ist. Ich habe schon die Dokumentationen größtenteils konsultiert, nur leider nichts dazu gefunden. Wäre über Links, Tips etc. sehr dankbar.


kOOni


hansa - Di 03.01.06 14:26

3. Versuch einer Antwort !


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
  DbDS.Close;
  DbDS.SelectSQL.Text := 'select RDB$RELATION_NAME from rdb$relations order by RDB$RELATION_NAME';
  DbDS.Open;
  DbDS.First;
  i := 0;
  while not DbDS.Eof do begin
    i := i + 1;
    DetailDS.Close;
    DetailDS.SelectSQL.Text := 'select count (*) AS ANZAHL from '+DbDS.FieldByName ('RDB$RELATION_NAME').AsString;
    DetailDS.Open;
    TableName := DbDS.FieldByName ('RDB$RELATION_NAME').AsString;
    Anzahl := DetailDS.FieldByName ('ANZAHL').AsString;
    if pos ('$',TableName) = 0 then begin
      if StrToInt (Anzahl) <> 0 then
        Memo1.Lines.Add(Tablename + blanks (20-length (TableName))  + '  '+ Anzahl)
      else
        Memo2.Lines.Add(Tablename + blanks (20-length (TableName))  + '  '+ Anzahl);
    end;
    DbDS.Next;
  end;
end;


Was soll das, nach dem Schreiben eines Beitrages zum Login aufgefortert zu werden ? :shock: Natürlich mit Verlust des Textes ? Das hat langsam keinen Zweck mehr. Deshalb jetzt kommentarlos. 8)


e86 - Do 05.01.06 14:38

Hallo,

danke dir für deine Antwort. Scheint so, als wären die SQL-Befehle in Firebird völlig anders, als in MySQL.

Was macht dieser Befehl?


Delphi-Quelltext
1:
select RDB$RELATION_NAME from rdb$relations order by RDB$RELATION_NAME                    


Hättest du vielleicht einen guten Link für eine allgemeine Befehlsübersicht? In IbPhänix habe ich nichts gefunden ...


kOOni


mkinzler - Do 05.01.06 14:47

Da alle Datenbankobjekte einer FB-Datenbank( wie bei den meißten Datenbanken) ebenfalls in Datenbanken abgelegt werden, kann man diese mit den normalen SQL-Befehlen auslesen.
Die Tabellen ( Systemtabellen) beginnen in FB mit dem Suffix RDB$.

RDB$RELATIONS beinhaltet die Tabellen, RDB$RELATION_FIELDS die Felder usw.

Dokus gibt es unter <a href="http://www.ibphoenix.com">IBPHOENIX</a>


hansa - Do 05.01.06 21:28

xy< SASCS


hansa - Do 05.01.06 21:39

und wieder halbe Seite futsch. Leider nicht vorher kopiert. Wenn das hier ankommt : das vorhin war ein Test. Jetzt heißt es : du kannst nur deine eigenen Beiträge bearbeiten, was ich ja tun wollte. 8)


hansa - Do 05.01.06 21:50

Zwischen 3 mal und 10 mal Login, obwohl sowieso eingeloggt, dann kommt der Beitrag an. :hair: Völlig unzumutbar. Und von Hand wurde kein Passwort eingegeben oder sonst was. :x Probiere jetzt max. 10 mal eine Antwort zu schreiben, deshalb nur kurz :

Das erste Select ermittelt alle vorhandenen Tabellen. Die gehe ich dann durch und ermittele per COUNT (*) die Anzahl der enthaltenen Datensätze. Für Tabelle ohne $ im Namen zeige ich dann Name und Anzahl DS an.


e86 - Sa 07.01.06 19:43

Hallo,

also ich habe mich etwas eingelesen in Firebird. Auf IBPhönix habe ich nur folgende Dokumentation gefunden, welche aber sehr unzureichend für mich ist.

FB 2.0 Release Notes [http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_download_20]

Nach einer Suche in der Knowledgebase wurde ich fündig (dazu siehe [url=http://www.ibphoenix.com/main.nfs?a=ibphoenix&l=;KNOWLEDGEBASE;ID='72']hier[/url] ):


Quelltext
1:
2:
3:
4:
5:
6:
SELECT RDB$RELATION_NAME
FROM RDB$RELATIONS
WHERE ((RDB$SYSTEM_FLAG = 0) OR
(RDB$SYSTEM_FLAG IS NULL)) AND
(RDB$VIEW_SOURCE IS NULL)
ORDER BY RDB$RELATION_NAME


Dieser Code bewirkt, dass ich alle Nicht-Systemtabellen angezeigt bekomme. Nur dabei sind auch Tabellen "IBE$", welche aber nicht von mir sind. Wie kann ich hier nur die bekommen, welche nur von "mir" sind? Also welche von irgendwelchen Usern erstellt wurden und nicht vom System selber.

Bei dem Statement bekomme ich scheinbar die Informationen über die verschiedenen Tabellen:


Quelltext
1:
2:
3:
4:
SELECT RDB$RELATION_NAME
FROM RDB$RELATIONS
WHERE (RDB$VIEW_SOURCE IS NULL)
ORDER BY RDB$RELATION_NAME


Aber das Ergebnis sieht ungefähr so aus:


Quelltext
1:
2:
3:
4:
IBE$AUTO_FIELDS
IBE$CATEGS                     
IBE$CHAMPS                     
...


Meine Frage ist nun: Wie kann ich auf diese Eigenschaften einer speziellen Tabelle zugreifen?

Wenn ich mir das jetzt richtig gedacht habe, müsste ich dann folgendes haben:

- Alle Tabellennamen einer Datenbank
- Alle Informationen einer Datenbank

Noch etwas. Ich arbeite mit IBEasy+, was sehr schön ist. Damit kann man schnell SQL-Statements senden. Ich habe bis jetzt nur mit MySQL gearbeitet und finde Firebird sehr komisch vom Aufbau und der Abfrage her, aber ich glaube, das gibt sich, wenn ich mich noch weiter damit befasse. Danke für die Antworten und Bemühungen bis jetzt und möge der Hansa nun auch mal ohne Wiedereinloggen posten können :P


kOOni
ps.: hättet ihr noch mehr Links für mich?


e86 - Sa 07.01.06 22:56

N' abend,

e86 hat folgendes geschrieben:
Wie kann ich hier nur die bekommen, welche nur von "mir" sind? Also welche von irgendwelchen Usern erstellt wurden und nicht vom System selber.


Diese Frage hat sich erledigt. Habe dazu folgendes konstruieren können :)


SQL-Anweisung
1:
2:
select * from rdb$relations where NOT (RDB$RELATION_NAME LIKE 'IBE$%'AND NOT (RDB$RELATION_NAME LIKE 'RDB$%')
ORDER BY RDB$RELATION_NAME


Dabei werden alle Tabellen angezeigt, die nur von Usern kreiert wurden.


kOOni

Moderiert von user profile iconUGrohne: Quote-Tag korrigiert.
Moderiert von user profile iconUGrohne: Code- durch SQL-Tags ersetzt


mkinzler - Sa 07.01.06 23:13

user profile icone86 hat folgendes geschrieben:

Meine Frage ist nun: Wie kann ich auf diese Eigenschaften einer speziellen Tabelle zugreifen?

Wenn ich mir das jetzt richtig gedacht habe, müsste ich dann folgendes haben:

- Alle Tabellennamen einer Datenbank

select rdb$field_name from rdb$relation_fields where rdb$relation_name = '<tabellenname>';
Zitat:

- Alle Informationen einer Datenbank

Verteilt in viele Systemtabellen.
Zitat:

Noch etwas. Ich arbeite mit IBEasy+, was sehr schön ist. Damit kann man schnell SQL-Statements senden. Ich habe bis jetzt nur mit MySQL gearbeitet und finde Firebird sehr komisch vom Aufbau und der Abfrage her,
?
Zitat:
aber ich glaube, das gibt sich, wenn ich mich noch weiter damit befasse. Danke für die Antworten und Bemühungen bis jetzt und möge der Hansa nun auch mal ohne Wiedereinloggen posten können :P


kOOni
ps.: hättet ihr noch mehr Links für mich?


Kann man sich bei IBEasy+ die Systemtabellen anzeigen lassen. Ich verwende IBexpert, von welchem es unter http://www.ibexpert.com eine freie Personal Edition gibt.

Gru? Markus.


e86 - Sa 07.01.06 23:23

Hallo Markus.

Danke für die Antwort. Ich weiß nicht, ob es das richtige SQL-Statement war... *G* Aber ich bekomme als Result von IbEasy+ folgende ÜBersicht:

RDB$FIELD_NAME
Null

RDB$RELATION_NAME
Null

RDB$FIELD_SOURCE
Null

RDB$QUERY_NAME
Null

RDB$BASE_FIELD
Null

[...]

RDB$FIELD_ID
Null

[...]


Ich zweifle deshalb etwas, weil alle Spalten mit "null" belegt sind und keine ausgefüllt ist. Obwohl die Tabelle mit Datensätzen gefüllt ist.

[EDIT]
Habe vergessen zu erwähnen das mein SQL-Query so aussah (Ich brauche ja alle Informationen der Tabelle):


Quelltext
1:
select * from rdb$relation_fields where rdb$relation_name = 'tabelle1';                    

[/EDIT]


kOOni


mkinzler - Sa 07.01.06 23:45

user profile icone86 hat folgendes geschrieben:

Ich zweifle deshalb etwas, weil alle Spalten mit "null" belegt sind und keine ausgefüllt ist. Obwohl die Tabelle mit Datensätzen gefüllt ist.

[EDIT]
Habe vergessen zu erwähnen das mein SQL-Query so aussah (Ich brauche ja alle Informationen der Tabelle):


Quelltext
1:
select * from rdb$relation_fields where rdb$relation_name = 'tabelle1';                    

[/EDIT]


kOOni

[delphi]
Mein Query zeigt natürlich nur die Felder von 'tabelle1' an und nicht alle der gesamten Datenbank. Willst du alle Felder Wissen mußt du eifach die where Bedingung weglassen.
Zitat:

Ich zweifle deshalb etwas, weil alle Spalten mit "null" belegt sind und keine ausgefüllt ist. Obwohl die Tabelle mit Datensätzen gefüllt ist.


In dieser Tabelle sind viele Felder NULL.
Versuchsa mal mit

select rdb$field_name from rdb$relation_fields


e86 - Sa 07.01.06 23:49

Hallo,

mit deinem letzten Statement:


SQL-Anweisung
1:
select rdb$field_name from rdb$relation_fields                    


bekomme ich einfach eine Liste mit allen Tabellennamen. Das will ich ja nicht. Ich möchte alle Tabellennamen habe, welche NICHT vom System sondern von einem User erstellt wurden.

Dies habe ich ja schon erreicht.

Nun suche ich nur noch das Statement für das Abfragen von Informationen einer bestimmten Tabelle.


kOOni
ps.: Anbei, du hast hier glaub ich das ganze Design mit deinem Beitrag zerschmiessen :P ^^

Moderiert von user profile iconUGrohne: Code- durch SQL-Tags ersetzt


mkinzler - Sa 07.01.06 23:59


SQL-Anweisung
1:
2:
select RDB$RELATION_NAME, rdb$field_name from rdb$relation_fields where NOT (RDB$RELATION_NAME LIKE 'IBE$%'AND NOT (RDB$RELATION_NAME LIKE 'RDB$%')
ORDER BY RDB$RELATION_NAME

zeigt dir eine Liste aller Felder an die Teil einer systemtabelle oder einer IBEasy+-Tabelle sind.

Moderiert von user profile iconUGrohne: Code- durch SQL-Tags ersetzt


e86 - So 08.01.06 00:08

Ähm,

irgendwie reden wir einander vorbei. Was du mir bis jetzt geschickt hast, dass hab ich ja schon alles realisiert. :)

Ich möchte jetzt nur noch wissen,

- wie ich alle Informationen (Tabellentyp, Collation, Comment ...) einer BESTIMMTEN Tabelle abfragen kann und...

- ... wie ich mir alle Eigenschaften der Spalten einer BESTIMMTEN Tabelle zurückgeben lassen kann. Also der Datentyp, Name, Länge der Spalte bzw. der Spalten. Dabei ist auch, ob es eine PRIMARY KEY Spalte ist, ob sie NOT NULL sein darf etc...

Wie gesagt, ich brauche die Informationen zu den Tabellen und den deren Spalten. Nicht den NAMEN aller Tabellen (das hab ich ja schon) und keine Auflistung der SPALTENNAMEN ohne dazugehörige Informationen.


kOOni


mkinzler - So 08.01.06 00:33

Wie gesagt befinden sich diese Informationen auf mehrere Systemtabellen verteilt.

Informationen zu den Constraints(PK, FK) befinden sich in der Tabelle rdb$relation_constraints), Informationen zu den Feldtypen kann über über das Feld rdb$field_source aus der Tabelle rdb&fileds geholt werden.

Zitat:
wie ich alle Informationen (Tabellentyp, Collation, Comment ...) einer BESTIMMTEN Tabelle abfragen kann und...

Was meinst du mit Tabellentyp?


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
select
    f.RDB$RELATION_NAME, f.rdb$field_name,
    s.rdb$field_length
from
    rdb$relation_fields f, rdb$fields s
where
     NOT (RDB$RELATION_NAME LIKE 'IBE$%'AND NOT (RDB$RELATION_NAME LIKE 'RDB$%'and
     s.rdb$field_name = f.rdb$field_source
ORDER BY RDB$RELATION_NAME


Moderiert von user profile iconUGrohne: Code- durch SQL-Tags ersetzt


e86 - So 08.01.06 12:15

Hallo,

danke für die Antwort. Jetzt weiß ich, auf was du hinaus willst. Dies scheint zu funktionieren. Nun habe ich den Namen und die Länge der Felder.

Hast du dafür irgendwie einen Link, wo eine Übersicht über diese Befehle ist?

Nachtrag:

Mit dem Tabellentyp meinte ich den Datentyp der Tabelle. Bin ich von MySQL her gewöhnt, da es dort bspw. MyISAM gibt. Aber den brauche ich nun nicht mehr.

kOOni


e86 - So 08.01.06 12:40

Hallo,


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
select
 f.rdb$field_name, s.RDB$Field_Length, s.RDB$field_type, s.RDB$description, 
 f.rdb$character_set_name
from
 rdb$relation_fields f, rdb$fields s
where
 NOT (RDB$RELATION_NAME LIKE 'IBE$%'AND NOT (RDB$RELATION_NAME LIKE 
 'RDB$%'and s.rdb$field_name = f.rdb$field_source


Dieses Statement bwirkt die Fehlermeldung:


Quelltext
1:
Unbekannte Spalte: F                    


Wiso? Es besteht doch die Spalte und der Field_Name "Character_Set_Name" ist doch auch vorhanden ... :?


kOOni


mkinzler - So 08.01.06 13:02

user profile icone86 hat folgendes geschrieben:
Hallo,


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
select
 f.rdb$field_name, s.RDB$Field_Length, s.RDB$field_type, s.RDB$description, 
 f.rdb$character_set_name
from
 rdb$relation_fields f, rdb$fields s
where
 NOT (RDB$RELATION_NAME LIKE 'IBE$%'AND NOT (RDB$RELATION_NAME LIKE 
 'RDB$%'and s.rdb$field_name = f.rdb$field_source


Dieses Statement bwirkt die Fehlermeldung:


Quelltext
1:
Unbekannte Spalte: F                    


Wiso? Es besteht doch die Spalte und der Field_Name "Character_Set_Name" ist doch auch vorhanden ... :?


kOOni

Nein die Tabelle rdb$relation_fields besitzt keinen Feld mit dem Namen.

Fehlermeldung IBExpert:

Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
F.RDB$CHARACTER_SET_NAME.
At line 3, column 4.

In die Tabelle rdb%fileds hat einen Fremdschlüssel rdb$character_set_id auf die Tabelle rdb$character_sets.

SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
select
 f.rdb$field_name,
 s.RDB$Field_Length, s.RDB$field_type, s.RDB$description, 
 c.rdb$character_set_name
from
 rdb$relation_fields f, rdb$fields s , rdb$character_sets c
where
 NOT (RDB$RELATION_NAME LIKE 'IBE$%'AND NOT (RDB$RELATION_NAME LIKE 
 'RDB$%'and s.rdb$field_name = f.rdb$field_source and
 c.rdb$character_set_id = s.rdb$character_set_id;


e86 - So 08.01.06 15:02

Hallo,

ich möchte mich erstmal für die Hilfe hier bedanken, besonders beim MKinzler!

Nun wäre ich fast fertig mit dem Statement. Was ich nun (endlich) habe ist:

- Spaltennamen
- Spaltentyp
- Null (ist es NULL oder NOT NULL)


Wegen dem Spaltentyp: Da steht eine Nummer. Ist das eine ID, welche ein Fremdschlüssel ist, der auf eine andere Tabelle verweist? Wie kann ich hierbei den 'richtigen' Datentyp alá CHAR oder INTEGER bspw. bestimmen?

Nun fehlt mir noch:

- Defaultwert
- PRIMARY KEY
- AUTO_INCREMENT

Ich habe aber keine entsprechenden Tabellen mit ähnlich klingenden Namen gefunden. :(

Anbei, wie war das nochmal, dass ich mir nur die Informationen der Spalten einer bestimmten Tabelle zurückgeben lasse? Hier geschieht dies ja für alle Tabellen, welche von Usern erstellt wurden.


kOOni


mkinzler - So 08.01.06 15:15

[quote="user profile icone86"
Wegen dem Spaltentyp: Da steht eine Nummer. Ist das eine ID, welche ein Fremdschlüssel ist, der auf eine andere Tabelle verweist? Wie kann ich hierbei den 'richtigen' Datentyp alá CHAR oder INTEGER bspw. bestimmen?
Zitat:

Da habe ich leider auch nichts gefunden. :(

Nun fehlt mir noch:

- Defaultwert
- PRIMARY KEY
- AUTO_INCREMENT

Ich habe aber keine entsprechenden Tabellen mit ähnlich klingenden Namen gefunden. :( [/quote]

-Informationen über Primär- und Fremdschlüssel findest du in der Tabelle rdb$relation_constraints.
-Autoincrement gibt es nicht direkt in FB, hier wird das z.B. über einen (Before Insert-)Trigger und einem Generator gelöst. Trigger in rdb$triggers, und Generatoren in rdb$generators
Zitat:

Anbei, wie war das nochmal, dass ich mir nur die Informationen der Spalten einer bestimmten Tabelle zurückgeben lasse? Hier geschieht dies ja für alle Tabellen, welche von Usern erstellt wurden.
kOOni

where um rdb$relation_name = '<tabellenname>' erweitern


e86 - So 08.01.06 15:42

Hallo,

habe nun folgendes SQL-Statement:


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
select
 f.rdb$field_name, s.RDB$Field_Length, s.RDB$field_type, s.RDB$description, 
 f.rdb$null_flag, lc.rdb$constraint_type

from
 rdb$relation_fields f, rdb$fields s, rdb$relation_constraints lc

where
 NOT (f.RDB$RELATION_NAME LIKE 'IBE$%'AND
 NOT (f.RDB$RELATION_NAME LIKE 'RDB$%'AND
 s.rdb$field_name = f.rdb$field_source  AND
 lc.rdb$relation_name = f.rdb$relation_name


Damit spuckt er mir aber komische Werte aus. Beispielsweise hat die Spalte "ID" 4 Einträge:


Quelltext
1:
2:
3:
4:
5:
6:
RDB$Field_Name | RDB$Field_Length | RDB$Field_Type | RDB$DESCRIPTION | RDB$NULL_FLAG | RDB$CONTRAINT_TYPE

ID | 2 | 7 | Null | 1 | NOT NULL
ID | 2 | 7 | Null | 1 | NOT NULL
ID | 2 | 7 | Null | 1 | PRIMARY KEY
ID | 2 | 7 | Null | 1 | FOREIGN KEY


Ich brauche aber nur den Wert, ob es ein PRIMARY KEY ist. Der Rest ist mir egal. Ich wollte gruppieren lasse mit :


SQL-Anweisung
1:
group by RDB$FIELD_NAME                    


Aber da kam der Fehler:

Ambiguous field name between table RDB$RELATION_FIELDS and table RDB$FIELDS
RDB$FIELD_NAME


Wie kann ich das bewerkstelligen, dass er mir nur ausgibt, ob die Zeile ein PRIMARY KEY ist?

Nun fehlt mir erst einmal nur noch dazu der Default-Wert. Wie kann ich auf diesen kommen?


kOOni


mkinzler - So 08.01.06 15:46

where lc.rdb$constraint_Type= 'PRIMARY KEY'


e86 - So 08.01.06 15:55

LOL,

jetzt bekomme ich zurück, dass meine 3 Felder alle Primärschlüssel sind. :roll: Und das Komische dabei ist, dass die Felder NOT NULL, PRIMARY KEY und FOREIGN KEY sind.. :?

Irgendwie stehe ich da total auf dem Schlauch. Hier dazu einmal vorsichtshalber der SQL-Befehl für die Tabellenbeschreibung:


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
/* Table: TABELLE1, Owner: SYSDBA */
CREATE TABLE "TABELLE1"
(
  "ID"  SMALLINT NOT NULL,
  "NAME"  CHAR(30NOT NULL,
  "ALTER"  SMALLINT,
 PRIMARY KEY ("ID")
);


Da steht doch, dass nur die ID ein PRIMARY KEY ist... :?

Also, wie kann ich mir den Defaultwert für die Spalten zurückgeben lassen? Und wie
bekomme ich heraus, ob eine Spalte PRIMARY KEY ist oder nicht?


Danke,
kOOni


mkinzler - So 08.01.06 16:08

Zitat:

Also, wie kann ich mir den Defaultwert für die Spalten zurückgeben lassen?


rdb$default_value

Zitat:
Und wie
bekomme ich heraus, ob eine Spalte PRIMARY KEY ist oder nicht?


Nicht in einer Abfrage. Über zweite Abfrage

SQL-Anweisung
1:
select count (rdb$constraint_type) where rdb$relation_name = <relation_name> and rdb§relation_type ='PRIMARY_KEY';                    

wenn count = 1 dann Primary Key oder das ganze in eine SP verpacken.


e86 - So 08.01.06 17:26

Ok,

wie komme ich jetzt an die Datentypen der Spalten selber? In der Übersicht stehen bei mir nur Zahlen wie 7, 14 usw... :?


kOOni


mkinzler - So 08.01.06 17:34

user profile icone86 hat folgendes geschrieben:
Ok,

wie komme ich jetzt an die Datentypen der Spalten selber? In der Übersicht stehen bei mir nur Zahlen wie 7, 14 usw... :?


kOOni


Durch Vergleichen mit den Typen der Tabelle 16 ist BigInt, 14 ist Char, 7 ist SmallInt usw.

Könnte man bei der Lösung in SP in Klartext zurückgeben.


e86 - So 08.01.06 18:02

Hallo,

Zitat:
Durch Vergleichen mit den Typen der Tabelle 16 ist BigInt, 14 ist Char, 7 ist SmallInt usw.

Könnte man bei der Lösung in SP in Klartext zurückgeben.


Welche Tabelle bei den Datentypen meinst du? Könntest du mir dies bitte in einem SQL-Statement zeigen :)

Und was ist "SP"?


kOOni


mkinzler - So 08.01.06 18:24

user profile icone86 hat folgendes geschrieben:


Welche Tabelle bei den Datentypen meinst du? Könntest du mir dies bitte in einem SQL-Statement zeigen :)

Und was ist "SP"?


Stored Procedure


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
SET TERM ^ ;

CREATE PROCEDURE "Tabelleninfo" (
    TABELLE CHAR(32))
RETURNS (
    NAME CHAR(32),
    FIELDLEN SMALLINT,
    FTYPE CHAR(16),
    NULLFLAG CHAR(8),
    ISPK CHAR(12),
    ISFK CHAR(12),
    DESCRIP VARCHAR(128))
AS
DECLARE VARIABLE TTYPE SMALLINT;
DECLARE VARIABLE TANZ SMALLINT;
begin
  for
  select
      f.rdb$field_name, s.RDB$Field_Length, s.RDB$field_type,
      s.RDB$description, f.rdb$null_flag
  from
     rdb$relation_fields f, rdb$fields s 
  where
     f.rdb$relation_name = :tabelle and
     NOT (f.RDB$RELATION_NAME LIKE 'IBE$%'AND
     NOT (f.RDB$RELATION_NAME LIKE 'RDB$%'AND
     s.rdb$field_name = f.rdb$field_source
  into
     :name, :Fieldlen, :ttype, :Descrip, :NullFlag
     do
     begin
        if (:ttype = 7then ftype = 'SmallInt';
        if (:ttype = 16then ftype = 'BigInt';
        if (:ttype = 14then ftype= 'Char';
        if (:ttype = 37then ftype= 'Varchar';
/*       for select
             count (rdb$constraint_type)
           from
              rdb$relation_constraints
          where
              rdb$relation_name = :TABELLE and
              RDB$CONSTRAINT_TYPE = 'PRIMARY_KEY'
          into
              :TANZ
          do
          begin
              if (:TANZ = 1) then
              begin
                  ISPK = 'PRIMARY_KEY' ;
              end
              else
              begin
                  ISPK = '';
              end
          end  */

       suspend;
     end
end
^

SET TERM ; ^

GRANT EXECUTE ON PROCEDURE "Tabelleninfo" TO SYSDBA;


e86 - So 08.01.06 18:54

Ähm..

ich frage jetzt einfach mal ganz dumm, ob du mir das nicht auch als reines SQL-Statement schreiben könntest. :oops:

Ich brauche dies in einer Anwendung und da ich mit diesen SP's keine Ahnung hab und ich mächtig unter Zeitdruck stehe, würde ich es gerne als reines SQL-Statement haben. Wenn das ginge.

Statement muss können:

- Rückgabe der Spaltennamen, Spaltentypen, Spaltenlänge, der Defaultwert und ob sie NULL sein können
- dabei sollte dies nur von einer vorher angegebenen Tabelle gemacht werden

Wäre sehr schön, wenn du das schreiben könntest :) :P


kOOni


mkinzler - So 08.01.06 19:07

user profile icone86 hat folgendes geschrieben:
Ähm..

ich frage jetzt einfach mal ganz dumm, ob du mir das nicht auch als reines SQL-Statement schreiben könntest. :oops:

Ich brauche dies in einer Anwendung und da ich mit diesen SP's keine Ahnung hab und ich mächtig unter Zeitdruck stehe, würde ich es gerne als reines SQL-Statement haben. Wenn das ginge.


Das geht leider nicht, da SQL mengenorientiert ist. PL/SQL von SP's und Triggern kennt weitere Befehle wie if then else usw.
Du kannst aber die Ersetztung der typids durch die Klartextbeschreibung in deinem Programm machen.
Um festzustellen welches Feld ein Primärschlüssel ist brauchst du eine 2. Abfrage, welche ich in der SP in einer Schleife für jede Zeile des Ergebnisses mache.

SP werden direkt in die datenbank geschrieben und werden auch direkt von ihr ausgeführt. man kann auf sie wie auf Tabellen/Views zugreifen: in meinem Beispiel:

SQL-Anweisung
1:
 select * from "Tabelleninfo"( <tabellenname>;                    

[/quote]

Anlegen kannst du sie mit Hilfe eines Admintool ( wie IBConsole, IbExpert, IBEasy+, Marathon, usw.)
Statement muss können:

- Rückgabe der Spaltennamen, Spaltentypen, Spaltenlänge, der Defaultwert und ob sie NULL sein können
- dabei sollte dies nur von einer vorher angegebenen Tabelle gemacht werden

Wäre sehr schön, wenn du das schreiben könntest :) :P


kOOni[/quote]

Komplette SP:


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
SET TERM ^ ;

CREATE PROCEDURE "Tabelleninfo" (
    TABELLE CHAR(32))
RETURNS (
    NAME CHAR(32),
    FIELDLEN SMALLINT,
    FTYPE CHAR(16),
    NULLFLAG CHAR(8),
    ISPK CHAR(12),
    ISFK CHAR(12),
    DESCRIP VARCHAR(128))
AS
DECLARE VARIABLE TTYPE SMALLINT;
DECLARE VARIABLE TANZ SMALLINT;
begin
  for
  select
      f.rdb$field_name, s.RDB$Field_Length, s.RDB$field_type,
      s.RDB$description, f.rdb$null_flag
  from
     rdb$relation_fields f, rdb$fields s 
  where
     f.rdb$relation_name = :tabelle and
     NOT (f.RDB$RELATION_NAME LIKE 'IBE$%'AND
     NOT (f.RDB$RELATION_NAME LIKE 'RDB$%'AND
     s.rdb$field_name = f.rdb$field_source
  into
     :name, :Fieldlen, :ttype, :Descrip, :NullFlag
     do
     begin
        if (:ttype = 7then ftype = 'SmallInt';
        if (:ttype = 16then ftype = 'BigInt';
        if (:ttype = 14then ftype= 'Char';
        if (:ttype = 37then ftype= 'Varchar';
        for select
             count (rdb$constraint_type)
           from
              rdb$relation_constraints c
          where
              c.rdb$relation_name = :TABELLE and
              c.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' and
              c.rdb$index_name inselect
                                       rdb$index_name
                                   from
                                       rdb$index_segments
                                   where rdb$field_name = :name )
          into
              :TANZ
          do
          begin
              if (:TANZ = 1then
              begin
                  ISPK = 'PRIMARY KEY' ;
              end
              else
              begin
                  ISPK = '';
              end
          end
       suspend;
     end
end
^

SET TERM ; ^

GRANT EXECUTE ON PROCEDURE "Tabelleninfo" TO SYSDBA;


Gruß Markus.


e86 - So 08.01.06 19:44

N'abend,

wie muss ich folgenden SQL-Befehl ändern, damit dieser nur für eine bestimmte Tabelle ausgeführt wird?


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
SELECT f.rdb$field_name as FieldName,
 s.RDB$Field_Length as FieldLength, 
 s.RDB$field_type as FieldType, 
 f.rdb$null_flag as NullFlag 

FROM   rdb$relation_fields f, rdb$fields s 

WHERE  
 NOT (f.RDB$RELATION_NAME LIKE 'IBE$%'AND 
 NOT (f.RDB$RELATION_NAME LIKE 'RDB$%'AND 
 s.rdb$field_name = f.rdb$field_source


Es soll für die Tabelle "Tabelle1" sein.

Nachtrag:
Ich muss es ohne Stored Procedures ausführen!


kOOni


mkinzler - So 08.01.06 19:55

user profile icone86 hat folgendes geschrieben:
N'abend,

wie muss ich folgenden SQL-Befehl ändern, damit dieser nur für eine bestimmte Tabelle ausgeführt wird?


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
SELECT f.rdb$field_name as FieldName,
 s.RDB$Field_Length as FieldLength, 
 s.RDB$field_type as FieldType, 
 f.rdb$null_flag as NullFlag 

FROM   rdb$relation_fields f, rdb$fields s 

WHERE  
 NOT (f.RDB$RELATION_NAME LIKE 'IBE$%'AND 
 NOT (f.RDB$RELATION_NAME LIKE 'RDB$%'AND 
 s.rdb$field_name = f.rdb$field_source


Es soll für die Tabelle "Tabelle1" sein.

Nachtrag:
Ich muss es ohne Stored Procedures ausführen!


kOOni


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
SELECT f.rdb$field_name as FieldName,
 s.RDB$Field_Length as FieldLength, 
 s.RDB$field_type as FieldType, 
 f.rdb$null_flag as NullFlag 

FROM   rdb$relation_fields f, rdb$fields s 

WHERE 
 f.rdb$relation_name = 'Tabelle1'  and 
 NOT (f.RDB$RELATION_NAME LIKE 'IBE$%'AND 
 NOT (f.RDB$RELATION_NAME LIKE 'RDB$%'AND 
 s.rdb$field_name = f.rdb$field_source


e86 - So 08.01.06 20:31

Hallo,

das Ergebnis ist eine Tabelle, in der alle Werte "null" sind. Scheint so, als würde er die Tabelle nicht finden, obwohl es sie doch gibt.. :?

Kann es sein, dass wir die falsche Systemtabelle abfragen?


kOOni


mkinzler - So 08.01.06 20:44

Versuchs mal mit

SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
SELECT f.rdb$field_name as FieldName,
 s.RDB$Field_Length as FieldLength, 
 s.RDB$field_type as FieldType, 
 f.rdb$null_flag as NullFlag 

FROM   rdb$relation_fields f, rdb$fields s 

WHERE 
 Upper(f.rdb$relation_name) = Upper('Tabelle1')  and 
 NOT (f.RDB$RELATION_NAME LIKE 'IBE$%'AND 
 NOT (f.RDB$RELATION_NAME LIKE 'RDB$%'AND 
 s.rdb$field_name = f.rdb$field_source


Query an sich funktioniert kann also nur an Gro/Kleinschreibung ( Dialekt 3?) liegen.


e86 - So 08.01.06 20:51

LOL,

ok, es geht :P


kOOni