Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird embedded DB mit API (SELECT Anweisung) (https://www.delphipraxis.net/80184-firebird-embedded-db-mit-api-select-anweisung.html)

matthes 4. Nov 2006 10:57

Datenbank: Firebird • Version: 1.5 • Zugriff über: API

Firebird embedded DB mit API (SELECT Anweisung)
 
Morschen,

Ich habe D2005PE und wollte mal mit Firebird Datenbanken arbeiten.
Habe mir die ZEOS Komponenten geladen und die DBC Demo ausprobiert.

Da mir die ZEOS aber zu umfangreich und kompliziert sind, dachte ich mir, mache ich doch das ganze Zeugs einfach selber - also direkt auf die DLL zugreifen.

Erstellen einer DB, anlegen von Tabellen und Einträgen usw. funktionert auch schon.
Nun will ich die Daten aus einer Tabelle mittels "SELECT * FROM TABELLE" auslesen.
Habe mir den Vorgang bei der ZEOS DBC Demo abgeschaut und auch den APIGuide von Firebird zu Rate gezogen, aber ich komme nicht weiter.

Wenn ich letztendlich mit isc_dsql_fetch die Daten hole, bekomme ich in der Variable >XSQLVar.sqldata< nur komisches Zeugs zurück. Mal #4 oder "{".
Spaltenname usw. werden richtig ausgelesen nur die Daten selber nicht.

Kann mir jemand helfen ?
Ich vermute mal, daß es ein Speicher-Zuordnungs-Problem ist, da nur .sqldata betroffen ist.

Delphi-Quellcode:
const Dialect = 3;

var TypeItem : Char;
    Statement_Length : integer;
    StatementBuffer : array [0..7] of Char;
    StatementTyp    : integer;
    i               : integer;
    XSQLVar         : PXSQLVAR;
    ListItem        : TListItem;
    SQL             : PCHAR;

Begin

  SQL := 'SELECT * FROM TESTUNG';

  GetMem(Out_SQLDA, XSQLDA_LENGTH(0));
  FillChar(Out_SQLDA^, XSQLDA_LENGTH(0), 0);
  OUT_SQLDA.sqln := 0;
  Out_SQLDA.sqld := 0;
  Out_SQLDA.version := SQLDA_VERSION1; // Wert = 1

  isc_dsql_alloc_statement2(@STATUS_VECTOR,@DBHandle,@STMT_Handle);

  isc_dsql_prepare(@Status_Vector, @Tran_Handle, @Stmt_Handle, 0, SQL, Dialect, NIL);

  TypeItem := Char(isc_info_sql_stmt_type);
  isc_dsql_sql_info(@Status_Vector, @Stmt_Handle, 1, @TypeItem, SizeOf(StatementBuffer), StatementBuffer);

  if StatementBuffer[0] = Char(isc_info_sql_stmt_type) then
    begin
      Statement_Length := isc_vax_integer(@StatementBuffer[1], 2);
      StatementTyp := isc_vax_integer(@StatementBuffer[3], Statement_Length);
    end;

  isc_dsql_describe(@Status_Vector, @Stmt_Handle, Dialect, Out_SQLDA);

 if out_SQLda^.sqld > out_SQLda^.sqln then
  begin
    IbReAlloc(Out_SQLDA, XSQLDA_LENGTH(Out_SQLDA.sqln), XSQLDA_LENGTH(OUT_SQLDA.sqld));
    Out_SQLDA.sqln := Out_SQLDA.sqld;
    isc_dsql_describe(@STATUS_VECTOR,@Stmt_Handle,Dialect,out_SQLda);
  end;

  {$R-}
  for i := 0 to Out_SQLDA.sqld - 1 do
    begin
      XSQLVar := @Out_SQLDA.SqlVar[i];
      case XSQLVar.sqltype and (not 1) of
        SQL_BOOLEAN, SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_DATE,
        SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT,
        SQL_LONG, SQL_INT64, SQL_DOUBLE, SQL_FLOAT, SQL_D_FLOAT:
            if XSqlVar.sqllen = 0
               then IbReAlloc(XSqlVar.sqldata, 0, 1)
               else IbReAlloc(XSqlVar.sqldata, 0, XSqlVar.sqllen)
        SQL_VARYING: IbReAlloc(XSqlVar.sqldata, 0, XSqlVar.sqllen + 2)
      end;
      if (XSqlVar.sqltype and 1) <> 0
         then ReallocMem(XSqlVar.sqlind, SizeOf(Short))
         else XSqlVar.sqlind := nil;
    end;
  {$IFOPT D+}
    {$R+}
  {$ENDIF}
  isc_dsql_execute(@Status_Vector, @Tran_Handle, @Stmt_Handle, Dialect,NIL);

  while isc_dsql_fetch(@Status_Vector, @Stmt_Handle, Dialect, Out_SQLDA) = 0 Do
    Begin
     for i := 0 to Out_SQLDA.sqld do
      begin
        XSqlVar := @Out_SQLDA.sqlvar[i];
        ...

End;


Procedure IbReAlloc(var P; OldSize, NewSize: Integer);
Begin
  ReallocMem(Pointer(P), NewSize);
  if NewSize > OldSize then
    Fillchar((Pchar(P) + OldSize)^, NewSize - OldSize, #0);
End;

Hansa 4. Nov 2006 12:17

Re: Firebird embedded DB mit API (SELECT Anweisung)
 
Zitat:

Zitat von matthes
Da mir die ZEOS aber zu umfangreich und kompliziert sind, dachte ich mir, mache ich doch das ganze Zeugs einfach selber - also direkt auf die DLL zugreifen.

Und das ist tatsächlich Dein Ernst ? :shock: Man greift nicht direkt auf solch komplizierte Sachen zu, die man nicht genau kennt.

Hoffe fast und zwar in Deinem Interesse, daß hier keiner Antwort gibt. Einmal habe ich den eisernen Grundsatz, nicht direkt auf Hardware oder Betriebssystem zuzugreifen nicht beachtet. Einer hatte krachneuen Rechner bekommen und mein Programm lief nicht mehr drauf. Auf dem alten lief es jahrelang. Warum ? Es lag an einer direkten Speicher-Adressierung, die eigentlich ziemlich egal war. Denkste ! Im Endeffekt war die Ursache sogar "nur" die zu hohe Taktfrequenz dieses neuen Rechners. Die hat an einer Stelle für einen Zahlenüberlauf gesorgt. Es hat 3 Monate gedauert, bis das geklärt war. In Deinem Falll stellt sich sogar noch die Frage, was bei einem Versionswechsel los ist. Ich sag nur Murphy. :mrgreen:

matthes 4. Nov 2006 12:53

Re: Firebird embedded DB mit API (SELECT Anweisung)
 
Naja, soviel kann man da rein theoretisch nicht falsch machen.
Ich benutze einfach die Funktionen die mir die DLL von Firebird liefert,
reserviere ein wenig Speicher für Variablen und fertig. :???:
(So die Theorie :wink: )

Ich meine, es ist schon ein Unterschied ob ich auf eine DLL zugreife oder auf Hardware oder Betriebssystem zugreife.
Und Versionsunterschied gibt es so nicht, da die Datenbank in der DLL ist, die ich mitliefern werde.

Hansa 4. Nov 2006 13:02

Re: Firebird embedded DB mit API (SELECT Anweisung)
 
Oh je.

Zitat:

Zitat von matthes
Und Versionsunterschied gibt es so nicht, da die Datenbank in der DLL ist, die ich mitliefern werde.

Du willst so was auch noch auf die Menschheit los lassen ? :shock: Dann mach mal. :stupid:

matthes 4. Nov 2006 13:09

Re: Firebird embedded DB mit API (SELECT Anweisung)
 
Wo liegt das Problem ?
Kennst Du Firebird embedded ?

Der Firebird DB-Server befindet sich in einer DLL (von Firebird erstellt und mitgeliefert).
Wenn ich diese DLL mit ausliefere und mein Programm dahingehend ausrichte, mit dieser DLL zu arbeiten, kann eigentlich nix passieren.

Hansa 4. Nov 2006 13:45

Re: Firebird embedded DB mit API (SELECT Anweisung)
 
Natürlich kenne ich Firebird embedded. Nur würde mir im Traum nicht einfallen, auf die GDS32.DLL direkt zuzugreifen. Was jetzt, wenn die sich intern ändert und du kriegst es nicht mit ? Oder weißt nicht wo ? Eventuell heißt es dann : Programm mußte leider eingestampft werden. :lol: Die WinAPI ist ähnliche Sache. Da wird auch immer dran rumgefummelt. Manchmal gehts nicht anders. Aber ohne Not würde ich die auch in Ruhe lassen. Quasi "Ruhe in Frieden". :mrgreen: Wetten, daß die WinAPI-Programmierer in nächster Zukunft wohl Ärger kriegen ? Die Warnungen ab D6 lassen grüßen. Überhaupt schon bemerkt, daß in den PE-Versionen nicht nur DBEdit, DBGrid usw. fehlen, sondern auch Datasource & Co. ?

Zitat:

Zitat von matthes
..kann eigentlich nix passieren.

Die Hoffnung stirbt zuletzt. :mrgreen:

matthes 4. Nov 2006 13:58

Re: Firebird embedded DB mit API (SELECT Anweisung)
 
ZEOS macht doch nix anderes. Greift doch auch direkt zu.
Woran bei mir die ZEOS scheitert, ist, daß der soviele Classen, Typen, usw. hat, daß man (ich) nicht durchblickt wo der jetzt die Daten herholt. Wegen einer Information rennt der durch zig Units.

Zitat:

Überhaupt schon bemerkt, daß in den PE-Versionen nicht nur DBEdit, DBGrid usw. fehlen, sondern auch Datasource & Co. ?
Ja, ist mir durchaus schon aufgefallen :zwinker:
Will ich ja sowieso nicht verwenden. ZEOS DBC verwendet auch ein StringGrid und ich will meine VirtualTreeView behalten :)

matthes 4. Nov 2006 14:57

Re: Firebird embedded DB mit API (SELECT Anweisung)
 
Problem gelöst.

Hatte mich zusehr versteift auf das VOR dem isc_dsql_fetch, derweil lag das Problem dahinter.
nach
Delphi-Quellcode:
XSqlVar := @Out_SQLDA.sqlvar[i];
muß ein
Delphi-Quellcode:
SetString(Str,XSqlVar.sqldata+2,XSQLVar.sqllen);
hin.
Damit klappt es wenigstens erstmal mit den Strings.
Den Rest (DOUBLE, SHORT, ...) kann ich nun noch bei ZEOS nachschauen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:18 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