Results 1 to 15 of 15

Thread: SQL in Firebird/Lazarus - Ubuntu

  1. #1
    Senior Member
    Join Date
    Sep 2004
    Location
    BELGIE(Vilvoorde)
    Posts
    685

    Question SQL in Firebird/Lazarus - Ubuntu

    Heb een programma in Linux(Ubuntu 13.04) Lazarus 1.0.12 / FPC 2.6.2. met Firebird 2.5.2.
    Maar bij het maken van een query krijg ik ERRORS.
    In de form: Datamodule1 : de componenten TIBdatabase + TIBtransaction + TIBquery + Tdatasource.
    In de form: Formmain:
    Code:
    procedure TFormMain.BitBtn1Click(Sender: TObject);
    begin
      try
        DATAMODULE1.QueryF1.Close;
        DATAMODULE1.QueryF1.SQL.Text:=
          'SELECT r.NR, r.NAAM, r.ARTIEST, r.GENRE FROM DATAMODULE1.TESTTABLE1 r';
        DATAMODULE1.QueryF1.Open;
        DATAMODULE1.QueryF1.ExecSQL;
      except
        on E : Exception do
        begin
          ShowMessage('Exception class name = '+E.ClassName);
          ShowMessage('Exception message = '+E.Message);
        end;
      end;
    end;
    Errors:
    1) Exception class name=eibinterbaseerror.
    2) Exception message: Dynamic sql error


  2. #2
    Senior Member Wok's Avatar
    Join Date
    Dec 2002
    Location
    Alkmaar
    Posts
    2,085
    je moet verwijzen naar de tabel, en niet naar de datamodule. zo iets -> 'SELECT NR, NAAM, ARTIEST, GENRE FROM TESTTABLE1';

    de Tquery wijst naar de verbinding.
    er is een datasource die wijst naar je query
    en bv een dbgrid die wijst naar de datasource

    als je de ibdatabase actief maakt, zou je al een verbinding naar je database moeten kunnen maken.
    10.4.2, Delphi2010, of Lazarus 2.2.0

  3. #3
    Senior member mzwollo's Avatar
    Join Date
    Oct 2004
    Location
    Larserbos
    Posts
    155
    Ik werk niet met lazarus, maar dezelfde code in Delphi zou ook mislukken.

    Code:
    procedure TFormMain.BitBtn1Click(Sender: TObject);
    begin
      try
        DATAMODULE1.QueryF1.Close;
        DATAMODULE1.QueryF1.SQL.Text:=
          'SELECT r.NR, r.NAAM, r.ARTIEST, r.GENRE FROM TESTTABLE1 r';
    // DATAMODULE1. weggelaten
        DATAMODULE1.QueryF1.Open;
    // DATAMODULE1.QueryF1.ExecSQL;
      except
        on E : Exception do
        begin
          ShowMessage('Exception class name = '+E.ClassName);
          ShowMessage('Exception message = '+E.Message);
        end;
      end;
    end;
    zou wel werken.

  4. #4
    Senior Member
    Join Date
    Sep 2004
    Location
    BELGIE(Vilvoorde)
    Posts
    685

    Exclamation

    mzwollo,
    Heb copy/paste gedaan van de(uw) code.
    Krijg nog steeds ERROR:

    Exception message: Operation cannot be performed on an active dataset.

  5. #5
    Senior Member
    Join Date
    Sep 2004
    Location
    BELGIE(Vilvoorde)
    Posts
    685

    Exclamation

    Sorry voor mijn vorig bericht. HET WERKT WEL!

    Nu probeer ik iets moeilijker en daar loop ik nog vast.

    Code:
    procedure TFormMain.BitBtnZOEKClick(Sender: TObject);
    var
       VARthesequel      : String;
       VARthescope       : String;
       VARfoundNR        : String;
    
       VARsqlNR          : String;
       VARsqlNAAM        : String;
       VARsqlARTIEST     : String;
       VARsqlGENRE       : String;
    
    begin
      DATAMODULE1.QueryF1.Close;
      DATAMODULE1.QueryF1.SQL.Clear;
      VARsqlNR      := DATAMODULE1.IBTable1NR.AsString;
      VARsqlNAAM    := DATAMODULE1.IBTable1NAAM.AsString;
      VARsqlARTIEST := DATAMODULE1.IBTable1ARTIEST.AsString;
      VARsqlGENRE   := DATAMODULE1.IBTable1GENRE.AsString;
      {------------------------------------------------------------}
      VARthescope := 'WHERE';
         //showmessage('check=false');
      IF not (VARsqlNR = '') then VARthescope := VARthescope + ' NR = "' + VARsqlNR + '"';
      IF not (VARsqlNAAM = '') then
      begin
        if not (VARthescope = 'WHERE')then VARthescope := VARthescope + ' AND';
        VARthescope := VARthescope + ' NAAM LIKE "' + '%' + VARsqlNAAM + '%"';
      end;
      {------------------------------------------------------------}
      IF not (VARsqlARTIEST = '') then
      begin
        if not (VARthescope = 'WHERE') then VARthescope := VARthescope + ' AND';
        VARthescope := VARthescope +' ARTIEST LIKE "'+'%' + VARsqlARTIEST +'%"';
      end;
      {------------------------------------------------------------}
      IF not (VARsqlGENRE = '') then
      begin
        if not (VARthescope = 'WHERE')then VARthescope := VARthescope + ' AND';
        VARthescope := VARthescope +' MODEL LIKE "'+'%' + VARsqlGENRE +'%"';
      end;
      {------------------------------------------------------------}
      DATAMODULE1.IBTable1.cancel ;
       //    showmessage(VARthescope);
           { minstens een zoekveld ingevuld -> doe SQL}
      if not (VARthescope = 'WHERE') then
      begin
        VARthesequel := 'SELECT * FROM DATAMODULE1.IBTable1 ' +
        VARthescope + ';';
        basisSQLstring := VARthesequel;
        DATAMODULE1.QueryF1.SQL.Add(VARthesequel);
        DATAMODULE1.QueryF1.Open;
        LabelCOUNTquery.caption:='Gevonden'+' : '+ inttostr(DATAMODULE1.QueryF1.recordcount);
        case DATAMODULE1.QueryF1.RecordCount of
             0: begin
                  EditNR.text:='';
                  EditNAAM.text:='';
                  EditARTIEST.text:='';
                  EditGENRE.text:='';
                  Application.messagebox('Niets gevonden !',
                   'M E S S A G E', mb_OK + mb_Iconexclamation);
                 end; {0: begin}
        else DBGridZOEK.DataSource := DATAMODULE1.DSqueryF1;
        end {case}
      end
      else
       begin
         // geen zoekveld ingevuld -> naar eerste 
         DATAMODULE1.IBTable1.First;
         DBGridZOEK.DataSource := DATAMODULE1.DSIBTable1;
       end;
    end;
    Error: Dynamic Sql Error.

    Reeds bedankt.

  6. #6
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Leer het concept van parameters.

    Bij parameters maak je een query als 'select * from sometable where id=:id and name ilike :name'

    En dan kan je in de params property per parameter (:id, :name) instellen wat moet matchen. (en als je de ilike niet wilt geef je gewoon % mee).

    Of misschien als tijdelijke maatregel kijken of er een "prepared" property is en die op false zetten.

    De error klinkt alsof de query geprepared is, en de db er later achter komt dat de SQL gewijzigd is.

  7. #7
    Senior member mzwollo's Avatar
    Join Date
    Oct 2004
    Location
    Larserbos
    Posts
    155
    Code:
        VARthesequel := 'SELECT * FROM DATAMODULE1.IBTable1 ' +
    moet worden:

    Code:
        VARthesequel := 'SELECT * FROM IBTable1 ' +

  8. #8
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ik zal je de routine geven, die ik altijd gebruik voor zulke acties.
    Ik gebruik het meerdere keren met 1 routine (NewQuery).
    Omdat het puur pascal is, zal het ook wel werken in Lazarus / FPC

    (typfouten onder voorbehoud)
    Attached Files Attached Files

  9. #9
    Senior Member
    Join Date
    Sep 2004
    Location
    BELGIE(Vilvoorde)
    Posts
    685
    wzwollo,

    hier aangepaste code:
    Code:
    procedure TFormMain.BitBtnZOEKClick(Sender: TObject);
    var
       VARthesequel    : String;
       VARthescope     : String;
       VARfoundNR      : String;
       VARsqlNR        : String;
       VARsqlNAAM      : String;
       VARsqlARTIEST   : String;
       VARsqlGENRE     : String;
    begin
      DATAMODULE1.QueryF1.Close;
      DATAMODULE1.QueryF1.SQL.Clear;
      VARsqlNR      := DATAMODULE1.IBTable1NR.AsString;
      VARsqlNAAM    := DATAMODULE1.IBTable1NAAM.AsString;
      VARsqlARTIEST := DATAMODULE1.IBTable1ARTIEST.AsString;
      VARsqlGENRE   := DATAMODULE1.IBTable1GENRE.AsString;
      {------------------------------------------------------------}
      VARthescope := 'WHERE';
      IF not (VARsqlNR = '') then VARthescope := VARthescope + ' NR = "' + VARsqlNR + '"';
      IF not (VARsqlNAAM = '') then
      begin
        if not (VARthescope = 'WHERE')then VARthescope := VARthescope + ' AND';
        VARthescope := VARthescope + ' NAAM LIKE "' + '%' + VARsqlNAAM + '%"';
      end;
      {------------------------------------------------------------}
      IF not (VARsqlARTIEST = '') then
      begin
        if not (VARthescope = 'WHERE') then VARthescope := VARthescope + ' AND';
        VARthescope := VARthescope +' ARTIEST LIKE "'+'%' + VARsqlARTIEST +'%"';
      end;
      {------------------------------------------------------------}
      IF not (VARsqlGENRE = '') then
      begin
        if not (VARthescope = 'WHERE')then VARthescope := VARthescope + ' AND';
        VARthescope := VARthescope +' MODEL LIKE "'+'%' + VARsqlGENRE +'%"';
      end;
      {------------------------------------------------------------}
      {------------------------------------------------------------}
      DATAMODULE1.IBTable1.cancel ;
      { minstens een zoekveld ingevuld -> doe SQL}
      if not (VARthescope = 'WHERE') then
      begin
        VARthesequel := 'SELECT * FROM IBTable1 ' +
        VARthescope + ';';
        basisSQLstring := VARthesequel;
        DATAMODULE1.QueryF1.SQL.Add(VARthesequel);
        DATAMODULE1.QueryF1.Open;
        LabelCOUNTquery.caption:='Gevonden'+' : '+ inttostr(DATAMODULE1.QueryF1.recordcount);
        case DATAMODULE1.QueryF1.RecordCount of
             0: begin
                  EditNR.text:='';
                  EditNAAM.text:='';
                  EditARTIEST.text:='';
                  EditGENRE.text:='';
                  Application.messagebox('Niets gevonden !',
                   'M E S S A G E', mb_OK + mb_Iconexclamation);
                 end; {0: begin}
        else DBGridZOEK.DataSource := DATAMODULE1.DSqueryF1;
        end {case}
      end
      else
       begin
         { geen zoekveld ingevuld -> goto first record }
         DATAMODULE1.IBTable1.First;
         DBGridZOEK.DataSource := DATAMODULE1.DSIBTable1;
       end;
    end;

    Nog ERROR:
    Dynamic Sql Error: Sql error code = -204 Table unknown IBTABLE1.

    Wat nu?

    jkuiper : Bedankt, maar dit gaat mijn petje ver te boven!

  10. #10
    Tsja, dan zal de tabel IBTABLE1 wellicht niet bestaan?
    Misschien TESTTABLE1 wel ?

  11. #11
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ik snap totaal niet wat je met IBTable aan het doen bent.
    Als je iets moet zoeken uit een tabel, maak je geen gebruik van een tabel om daarmee een query te maken. Immers zijn deze gegevens altijd aanwezig.

    Hier heb je een voorbeeld van jouw code, waarbij gebruik wordt gemaakt van parameters.
    Ik heb het zo opgebouwd dat je of zoekt op een nummer (id) of op de resterende velden. Ik mag er vanuit gaan dat NR in jouw voorbeeld een uniek getal is en niet belangrijk is voor je andere zoekopdrachten. Een uniek nummer geeft jou al een record terug en dan is de combinatie met de andere velden overbodig.
    delphi Code:
    1. procedure TFormMain.BitBtnZOEKClick(Sender: TObject);
    2. var
    3.    VARsqlNR          : String;
    4.    VARsqlNAAM        : String;
    5.    VARsqlARTIEST     : String;
    6.    VARsqlGENRE       : String;
    7.    Query             : string;
    8. begin
    9.   {
    10.     Deze constructie werkt met parameters.
    11.     De querycomponent kan op basis van die gegevens de ont-
    12.     brekende waarde invullen, zodat de zoekopdracht voltooid
    13.     kan worden.
    14.   }
    15.   try
    16.     QueryF1.disablecontrols;  //zet de focus uit voor de grid
    17.     QueryF1.active := false;
    18.     QueryF1.SQL.Clear;
    19.     Query := 'SELECT NR,NAAM,ARTIEST,GENRE,TITEL,JAAR FROM tracks';
    20.     // wat doet de IBTable eigenlijk?
    21.     VARsqlNR      := Edit1.Text;
    22.     VARsqlNAAM    := Edit2.Text;
    23.     VARsqlARTIEST := Edit3.Text;
    24.     VARsqlGENRE   := Edit4.Text;
    25.     if VARsqlNR > '' then
    26.     begin
    27.       QueryF1.SQL.Text := Query + 'WHERE NR = :nr';
    28.       QueryF1.parambyname('nr').AsString := VARsqlNR;
    29.     end else
    30.     begin
    31.       QueryF1.SQL.Text := Query + 'WHERE NAAM LIKE :naam AND ' +
    32.                                   'AND ARTIEST LIKE artiest AND GENRE LIKE :genre';
    33.       //format maakt een string aan met een % ervoor en erna
    34.       QueryF1.parambyname('naam').AsString    := format('%s%s%s','%',VARsqlNAAM,'%');
    35.       QueryF1.parambyname('artiest').AsString := format('%s%s%s','%',VARsqlARTIEST,'%');
    36.       QueryF1.parambyname('genre').AsString   := format('%s%s%s','%',VARsqlGENRE,'%');
    37.     end;
    38.     QueryF1.active := true;
    39.     if QueryF1.recordcount = 0 then
    40.       showmessage('niets gevonden');
    41.   finally
    42.      QueryF1.enablecontrols;  //zet de focus aan voor de grid
    43.   end;
    44. end;

  12. #12
    Senior member mzwollo's Avatar
    Join Date
    Oct 2004
    Location
    Larserbos
    Posts
    155
    @Seghele
    De code van John Kuiper is mooi, maar een kleine wijziging in jouw eigen code doet de procedure waarschijnlijk al werken.
    Hoe heet de tabel in Firebird met de velden NR, NAAM, ARTIEST en GENRE?
    Stel dat die tabel tblTracks heet, wijzig dan de code regel in:

    Code:
    VARthesequel := 'SELECT * FROM tblTracks ' +

  13. #13
    Senior Member
    Join Date
    Sep 2004
    Location
    BELGIE(Vilvoorde)
    Posts
    685

    Exclamation

    jkuiper, ik denk dat stilaan de oplossing komt!

    Code:
    procedure TFormMain.BitBtnZOEKClick(Sender: TObject);         
    var
       VARsqlNR          : String;
       VARsqlNAAM        : String;
       VARsqlARTIEST     : String;
       VARsqlGENRE       : String;
       Query             : string;
    begin
      VARsqlNR      := EditNR.Text;
      VARsqlNAAM    := EditNAAM.Text;
      VARsqlARTIEST := EditARTIEST.Text;
      VARsqlGENRE   := EditGENRE.Text;
      try
        //DATAMODULE1.QueryF1.disablecontrols;  //zet de focus uit voor de grid
        DATAMODULE1.QueryF1.active := false;
        DATAMODULE1.QueryF1.SQL.Clear;
        Query := 'SELECT NR,NAAM,ARTIEST,GENRE FROM testtable1';
    
        DATAMODULE1.QueryF1.SQL.Text := Query + ' WHERE NAAM LIKE :naam ' +
                                      'AND ARTIEST LIKE :artiest AND GENRE LIKE :genre';
        DATAMODULE1.QueryF1.parambyname('naam').AsString    := '%' + VARsqlNAAM +'%';
        DATAMODULE1.QueryF1.parambyname('artiest').AsString := '%' + VARsqlARTIEST + '%';
        DATAMODULE1.QueryF1.parambyname('genre').AsString   := '%' + VARsqlGENRE +'%';
        DATAMODULE1.QueryF1.active := true;
        if DATAMODULE1.QueryF1.recordcount = 0 then
           showmessage('niets gevonden');
      finally
         //DATAMODULE1.QueryF1.enablecontrols;  //zet de focus aan voor de grid
      end;
    end;
    Opzoeken volgend de "NR" heeft duidelijk geen zin in dit programma, dus laat ik de opzoeking ervan weg.
    Via parameter "format" geeft Lazarus een ERROR.
    Probleem is nu dat de query geen fouten geeft maar enkel het eerste record toont in de Grid na opzoeking via een van de velden NAAM/ARTIEST/GENRE.
    Bij zoeken naar een andere record geeft hij aan: "niets gevonden" en is de Grid dus leeg.

  14. #14
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Dat is toch logisch dat de grid leeg is als deze niet is gevonden.
    Maar als je zoekt op 'A' dan zal je toch meerdere records krijgen?

  15. #15
    Senior Member
    Join Date
    Sep 2004
    Location
    BELGIE(Vilvoorde)
    Posts
    685

    Thumbs up

    jkuiper,
    Sorry, beetje grieperig en dus niet helder van ...
    Inderdaad, alles klopt met de query.

    Hartelijk dank voor de steun.
    Zal je nog later nodig hebben, vrees ik !!!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •