Results 1 to 12 of 12

Thread: Bestand wordt aangemaakt, de velden niet

  1. #1
    Senior Member AntonSteen's Avatar
    Join Date
    Dec 2006
    Location
    IJsselmonde (Rotterdam)
    Posts
    352

    Bestand wordt aangemaakt, de velden niet

    Oke, ik ben eens lekker bezig, en loop tegen een probleempje aan.
    Ik probeer een database (sqlite), tijdens het aanroepen van de datamodule wordt het bestand aangemaakt, maar het maken van de velden word overgeslagen, en dat was nou net niet mijn idee!.
    Ik heb de code nu al twee keer overgeschreven, maar de fout blijft, dus ga ik er vanuit dat er in de code gewoon iets niet goed staat, ik kan er alleen niet achter komen wat.
    Zien jullie hier een oplossing in, krijg heel soms de melding "Database not assigned"

    Tegenwoordig maak ik gebruik van Lazarus, en wat ik al aangaf SQLite, die worden aangesproken via de standaard componenten, maar dat ter extra informatie.

    Code:
    procedure TDM1.DataModuleCreate(Sender: TObject);
    var
      DataFile : boolean;
      CreateTables : boolean;
    begin
      Connect1.Close;
      try
        Connect1.DatabaseName := 'dagboek.sdb';
        Connect1.Connected := True;
        DataFile := not FileExists(Connect1.DatabaseName);
        begin
          try
            Connect1.Open;
            CreateTables := not FileExists(Connect1.DatabaseName);
            if  CreateTables then
            begin
               SQLQ1.SQL.Add('CREATE TABLE "DAGBOEK"( '+
               '"DagboekID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,' +
               '"Datum" Date NOT NULL,' +
               '"Titel" VARCHAR(50),' +
               '"Omschrijving" MEMO);');
                SQLQ1.SQL.Add('CREATE UNIQUE INDEX "DAGBOEK_DagboekID_idx" ON "DAGBOEK"("DagboekID");');
                SQLQ1.ExecSQL;
            end;
            ShowMessage('Uw Dagboek is aangemaakt');
          except
            ShowMessage('Er was een probleem met het maken van het dagboek');
          end;
        end;
          except
            ShowMessage('Kan niet controleren of uw dagboek al bestaat');
          end;
        end;
    
    
    end.
    Alvast bedank
    Lazarus als hobby, en dan niet in de kroeg
    http://www.wavdsteen.com

  2. #2
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Sowieso zal ik die procedure niet in create doen, maar in een aparte procedure na de create. Als je met SQLdb werkt, werk je standaard met transacties.
    Ik zal het op die manier aanpakken:
    Delphi Code:
    1. function TDM1.CreateTables : string;
    2. var
    3.   SQLQ1  : TSQLquery ;
    4.   Transaction : TSQLTransaction;
    5. begin
    6.   SQLQ1  := TSQLquery.create(nil);
    7.   Transaction := TSQLTransaction.create(nil);
    8.   result := '';
    9.   try
    10.     if not FileExists(Connect1.DatabaseName) then
    11.     begin
    12.       if Connect1.Connected then
    13.       begin
    14.         Transaction.database := Connect1;
    15.         SQLQ1.database := Connect1;
    16.         SQLQ1.transaction := Transaction;
    17.         with SQLQ1.SQL do
    18.         begin
    19.            Add('CREATE TABLE dagboek (');
    20.            Add('  DagboekID integer NOT NULL PRIMARY KEY AUTOINCREMENT,');
    21.            Add('  Datum Date NOT NULL,');
    22.            Add('  Titel VARCHAR(50),');
    23.            Add('  Omschrijving MEMO,');
    24.            Add('  UNIQUE INDEX DAGBOEK_DagboekID_idx ON DAGBOEK ( DagboekID))');
    25.         end;
    26.         SQLQ1.ExecSQL;
    27.         Transaction.commit;
    28.       end else
    29.         result := 'Database is niet open';
    30.     end else
    31.       result := 'Database niet gevonden';
    32.   except
    33.     result := 'fout in procedure';
    34.   end;
    35. end;

    (Let niet op e.v.t. fouten. Dit is uit losse pols getypt)
    Delphi is great. Lazarus is more powerfull

  3. #3
    Marius
    Join Date
    Jul 2013
    Location
    Groningen
    Posts
    178
    Moeten de create table en de create index niet apart van elkaar uitgevoerd worden. Een TSqlQuery verwacht volgens mij geen twee commando's achterelkaar (voor zover ik het weet). Bestaat er misschien ook een TSqlScript?

    Maar misschien zit ik er naast want ik heb absoluut geen ervaring met sqllite of de tsqlquery...

  4. #4
    Senior Member AntonSteen's Avatar
    Join Date
    Dec 2006
    Location
    IJsselmonde (Rotterdam)
    Posts
    352
    Dank heren, ik gaat daar vanavond mee aan de slag.
    De uitkomst plaats ik uiteraard hier.
    Lazarus als hobby, en dan niet in de kroeg
    http://www.wavdsteen.com

  5. #5
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Quote Originally Posted by Marius2 View Post
    Moeten de create table en de create index niet apart van elkaar uitgevoerd worden. Een TSqlQuery verwacht volgens mij geen twee commando's achterelkaar (voor zover ik het weet). Bestaat er misschien ook een TSqlScript?

    Maar misschien zit ik er naast want ik heb absoluut geen ervaring met sqllite of de tsqlquery...
    Ik ook niet met SQLite. Maar het is SQL92, dus verwacht ik wel een combi van die twee in 1 query. Met MySQL en Firebird kan het in ieder geval wel.
    Delphi is great. Lazarus is more powerfull

  6. #6
    Volgens https://www.sqlite.org/lang_createtable.html

    In most cases, UNIQUE and PRIMARY KEY constraints are implemented by creating a unique index in the database.
    (The exceptions are INTEGER PRIMARY KEY and PRIMARY KEYs on WITHOUT ROWID tables.)
    Hence, the following schemas are logically equivalent:

    1. CREATE TABLE t1(a, b UNIQUE);
    2. CREATE TABLE t1(a, b PRIMARY KEY);
    3. CREATE TABLE t1(a, b);
      CREATE UNIQUE INDEX t1b ON t1(b);
    Dus voor jou zou het zoiets zijn:
    Code:
    CREATE TABLE "DAGBOEK"(
      "DagboekID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
      "Datum" Date NOT NULL,
      "Titel" VARCHAR(50),
      "Omschrijving" MEMO);
    Volgens de documentatie heb je de UNIQUE INDEX dus niet nodig omdat de PRIMARY KEY zelf al een index aanmaakt. Alleen als je bijvoorbeeld op een ander veld nog een index wilt maken zul je met UNIQUE-keyword kunnen werken,.

  7. #7
    Senior Member AntonSteen's Avatar
    Join Date
    Dec 2006
    Location
    IJsselmonde (Rotterdam)
    Posts
    352
    Oke, bijna anderhalve maand verder, kan ik het volgende melden, zo heb ik SQLite vervangen voor Firebird.
    Ik heb dan ook het volgende als test gemaakt, om te kijken of dit werkt, en dat doet het, de database word aangemaakt, en in de DBGrid worden de velden getoond.
    Nu zal dit niet het meest effectieve code zijn, en kan er denk ik best wel het één en ander aan verbeterd worden, dus suggesties zijn altijd welkom, evenals kritiek (opbouwend natuurlijk) en tips.
    Ik maak gebruik van Lazarus met de standaard componenten, en onder windows 7, Firebird is embedded


    procedure TDataModule1.DBMaken;
    var
    DataBaseFile : String;
    DBParams : TStringList;
    begin
    DatabaseFile := 'Jobhunter.fdb';
    Connect.HostName := '';
    Connect.DatabaseName := DatabaseFile;
    Connect.UserName := 'SYSDBA';
    Connect.Password := 'masterkey';
    Connect.CharSet := 'UTF8';
    Connect.Dialect := 3;
    DBParams := TStringList.Create;
    try
    DBParams.Add('PAGE_SIZE=16384');
    Connect.Params := DBParams;
    finally
    DBParams.Free;
    end;

    if (FileExists(DatabaseFile) = false) then
    begin
    TransAction.Active := false;
    Connect.Transaction := TransAction;
    Connect.CreateDB;
    Connect.Open;
    TransAction.StartTransaction;
    Connect.ExecuteDirect('CREATE TABLE Test (id VARCHAR(10), Testje VARCHAR(50));');
    TransAction.Commit;
    Connect.Close;
    end;
    end;
    De Velden worden op de volgende manier ingelezen

    procedure TDataModule1.DataModuleCreate(Sender: TObject);
    var
    DataBaseFile : String;
    DBParams : TStringList;
    begin
    DBMaken;
    DatabaseFile := 'Jobhunter.fdb';
    Connect.HostName := '';
    Connect.DatabaseName := DatabaseFile;
    Connect.UserName := 'SYSDBA';
    Connect.Password := 'masterkey';
    Connect.CharSet := 'UTF8';
    Connect.Dialect := 3;
    Connect.Connected := True;
    TransAction.DataBase := Connect;
    TransAction.Active := True;
    SQLQuery.DataBase := Connect;
    SQLQuery.SQL.Text := 'select * from TEST';
    SQLQuery.Active := True;
    DataSource1.DataSet := SQLQuery;
    end;
    Groetjes AntonSteen
    Last edited by AntonSteen; 17-Apr-15 at 12:04. Reason: Extra toevoeging
    Lazarus als hobby, en dan niet in de kroeg
    http://www.wavdsteen.com

  8. #8
    Ik zie dat je twee keer de hele initialisatie van Connect doet bij het aanmaken van je database. De eerste keer in DBMaken en de tweede keer in DataModuleCreate. Volgens mij hoef je dit alleen in DataModuleCreate te doen en daarna pas controleren of de database bestaat (en indien niet gewoon direct de Connect.CreateDB doen).

    Dus zoiets:
    Delphi Code:
    1. procedure TDataModule1.DataModuleCreate(Sender: TObject);
    2. var
    3.   DataBaseFile: String;
    4. begin
    5.   // eerst de complete initialisatie doen van Connect
    6.   DataBaseFile := 'Jobhunter.fdb';
    7.   Connect.HostName := '';
    8.   Connect.DatabaseName := DataBaseFile;
    9.   Connect.UserName := 'SYSDBA';
    10.   Connect.Password := 'masterkey';
    11.   Connect.CharSet := 'UTF8';
    12.   Connect.Dialect := 3;
    13.   Connect.TransAction := TransAction;
    14.  
    15.   // dan controleren of we de database aan moeten maken
    16.   if (FileExists(DataBaseFile) = false) then
    17.   begin
    18.     Connect.Params.Clear;
    19.     Connect.Params.Add('PAGE_SIZE=16384');
    20.     Connect.CreateDB;
    21.     Connect.Open;
    22.     Connect.TransAction.StartTransaction; // ik gebruik meestal Connect.TransAction zodat ik zeker weet dat ik de juiste transaction heb
    23.     Connect.ExecuteDirect('CREATE TABLE Test (id VARCHAR(10), Testje VARCHAR(50));');
    24.     Connect.TransAction.Commit;
    25.     Connect.Close;
    26.   end;
    27.  
    28.   // connect is al helemaal gevuld met de juiste gegevens dus die kunnen we blijven gebruiken
    29.   Connect.Params.Clear; // e.v. PAGE_SIZE weer weghalen uit params
    30.   Connect.Connected := true;
    31.   Connect.TransAction.Active := true;
    32.   SQLQuery.DataBase := Connect;
    33.   SQLQuery.SQL.Text := 'select * from TEST';
    34.   SQLQuery.Active := true;
    35.   DataSource1.DataSet := SQLQuery;
    36. end;

  9. #9
    Senior Member AntonSteen's Avatar
    Join Date
    Dec 2006
    Location
    IJsselmonde (Rotterdam)
    Posts
    352
    Dat ziet er een heel stuk korter uit Rik, dank je wel, ook zie ik wat andere wijzigingen, ik gaat het testen.
    Dank je wel
    Lazarus als hobby, en dan niet in de kroeg
    http://www.wavdsteen.com

  10. #10
    Senior Member AntonSteen's Avatar
    Join Date
    Dec 2006
    Location
    IJsselmonde (Rotterdam)
    Posts
    352
    Hmm, volgens jou list wat ik nu heb uitgevoerd krijg ik hem niet meer in de DBGrid.
    Lazarus als hobby, en dan niet in de kroeg
    http://www.wavdsteen.com

  11. #11
    Quote Originally Posted by AntonSteen View Post
    Hmm, volgens jou list wat ik nu heb uitgevoerd krijg ik hem niet meer in de DBGrid.
    Mmmm, Ik wel:
    Click image for larger version. 

Name:	PiR6G1W.png 
Views:	266 
Size:	38.4 KB 
ID:	6950
    Je had DataSource1 toch wel nog steeds aan DBGrid1 hangen, hé ?

  12. #12
    Senior Member AntonSteen's Avatar
    Join Date
    Dec 2006
    Location
    IJsselmonde (Rotterdam)
    Posts
    352
    Ja hoor, dat was hem, dom natuurlijk had het kunnen weten, dank je voor het mee denken
    Lazarus als hobby, en dan niet in de kroeg
    http://www.wavdsteen.com

Thread Information

Users Browsing this Thread

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

Tags for this Thread

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
  •