Programmieren mit dBASE PLUS: SQL-Datenbanken: Was ist zu beachten


Logische Felder Bearbeiten

Firebird kennt keine logischen Felder. Man kann aber stattdessen ein Zeichenfeld der Länge 1 verwenden, das für den Benutzer wie ein logisches Feld aussieht. Dazu verpassen wir einer Checkbox ein Zeichenfeld als Datalink. Vorher müssen wir die Ereignisse des betreffenden Zeichenfeldes zum Umwandeln des Datentyps verwenden. Im Ereignis beforeGetValue wandeln wir den in der Tabelle als Zeichen gespeicherten Wert in einen logischen Wert um. Das Gegenstück dazu ist das Ereignis canChange, hier wandeln wir den logischen Wert in ein Zeichen um.

  function Zeichenfeld_beforeGetValue
     return (this.value = 'y')
  function Zeichenfeld_canChange(newValue)
     this.value = iif(newValue = true, 'y','n')
     return false

Ausprobieren kann man das z.B. mit der Tabelle Sales aus der Firebird-Beispieldatenbank Employee. Dazu muss natürlich die Firebird-Beispieldatenbank installiert sein und ein ODBC-DSN. Gehen Sie im dBASE-Regiezentrum zum Reiter Tabellen und öffnen Sie die Firebird-Beispieldatenbank. Öffnen Sie den Formulardesigner und ziehen Sie aus der Feldpalette die Felder CUST_NO, und ORDER_DATE auf das Formular. Bei dem Feld PAID gehen wir anders vor. Wir klicken im Formdesigner auf das Formular, öffnen den Objektinspektor und vergewissern und, dass form.rowset gesetzt ist (form.sales1.rowset). Dann gehen wir im Objektinspektor von form.rowset.sales1 > fields > PAID und dann zum Reiter Methoden. Bei der Methode beforeGetValue klicken wir auf das Schraubenschlüssel-Symbol um Code für die Methode einzugeben. Das Ergebnis sieht so aus:

  function PAID_beforeGetValue
     return (this.value = 'y')

Zurück im Objektinspektor klicken wir auf die den Schraubenschlüssel hinter der Methode canChange und ergänzen folgenden Code:

 function PAID_canChange(newValue)
    this.value = iif(newValue = true, 'y','n')
    return false

Wegen eines Bugs in dBASE empfiehlt es sich, im Event onDesignOpen folgendes einzugeben:

 function form_onDesignOpen(bFromPalette)
    set procedure to program(1) additive
    return

Anschließend das Formular speichern und wieder öffnen. Jetzt ziehen wir eine Checkbox-Komponente auf das Formular, geben ihr den Namen CHECKBOXPAID und den Text Paid. Wenn wir nun versuchen im Objektinspektor der Checkbox ein Datalink zuzuweisen, erhalten wir immer noch eine Fehlermeldung. Also fügen wir die betreffende im Quellcode-Editor von Hand ein.

  this.CHECKBOXPAID = new CHECKBOX(this)
  with (this.CHECKBOXPAID)
     dataLink = form.sales1.rowset.fields["paid"]
     // usw. 
     text = "Paid"
  endwith

Speichern Sie anschließend das Formulars und probieren Sie es aus. Bei mir funktioniert's, ich hoffe bei Ihnen auch!

lookupSql Bearbeiten

Wenn Sie mit lookupSQL ein Nachschlagefeld festlegen, so kann die Nachschlagetabelle nur aus der benutzten Datenbank kommen. Bei der Angabe einer Tabelle mit einem vorgestellten Alias aus der BDE geht nicht. Es wird keine Referenz auf die Tabelle mit Alias akzeptiert

":meinAlias:meineTabelle" geht nicht "meineTabelle" geht

Benutzen Sie bitte für die Referenz einer Tabelle aus einer anderen Datenbank das lookupRowset.


Query Bearbeiten

requestLive Bearbeiten

Fehlermeldung:

Fehler der Datenbank-Engine: Tabelle ist schreibgeschützt.

Stellen Sie in der Query

requestLive = false

ein. Die Query versucht sonst ein beschreibbares Rowset zu erstellen was bei einer Query mit inner join Verknüpfungen nicht geht. Das Rowset mit inner join ist schreibgeschützt und verursacht diese Fehlermeldung. Dies betrifft auch viele andere SQL-Abfragen:

  • Abfragen mit Aggregatfunktionen (SUM,AVG, MIN, MAX)
  • Abfragen mit sonstigen Funktionen (SUBSTRING, CAST, EXTRACT etc.)
  • Abfragen mit GROUP BY

Sinnvoll ist es für das Query-Objekt zwei benutzerdefinierte Klassen anzulegen und immer davon abzuleiten. Eine für die beschreibbaren Abfragen und eine für die readonly-Abfragen.

indexName Bearbeiten

Fehlermeldung:

Fehler der Datenbank-Engine: Index nicht vorhanden

Wenn Sie mit

"select * from XYZ"

arbeiten kann im Rowset unter indexName der Name des Indexes ausgewählt werden.

Sobald Sie mit

"select feld1, feld2 u.s.w from XYZ"

die einzelnen Felder festlegen, die in der Sicht erscheinen sollen, führt die Angabe bei indexName zu einem Fehler. In diesem Falle ist mit order by zu arbeiten. Die Felder in der order by Klausel müssen nicht in der Feldliste der Abfrage enthalten sein.