- Live Cursor mit Satzzeiger
- satz orientiert, recno
- seek über ISAM Index
- Index mit For-Bedingung
- SQL Abfragen parallel möglich
- SQL Resultset kann indiziert werden
- Benutzer/Rechte werden im DataDictionary gepflegt
- nur SQL möglich
- SELECT immer eine Kopie des Ergebnisses
- UPDATE / INSERT wird nicht in der Kopie
mitgepflegt
- Index nur für Primary-, Unique- und
Fremdschlüssel nötig und sinnvoll
- case sensitiv, (nur kleinbuchtaben verwenden)
- Benutzer ist über Datenbank angelegt
:goto, :gotop, :gobottom
:fieldget, :fieldput
:recno (nicht konsistent)
:lastrec
:eof, :bof
:locate, :continue
:skip
:dbstruct (alle PQ Datentypen)
:fieldpos/-name/-type/-info
:fcount
:setfilter, immer clientside
:found
:close
:scatter, :gather
entfällt ersatzlos
:rlock/:flock/:unlock/:islocked
:recall
:deleted
:ordcreate/-list/-number/-key/-name
:reindex
:pack
:OpenServer()
:ordSetFocus(), [ordCondSet()]
:SetAOF()
:SetScope()
:Append()
:Delete()
:Commit()
:Zap()
:SetRelation()
SELECT * FROM <table> FETCH FIRST ROW ONLY
liest 1.Satz für Initalisierung ein.
In der Regel wird durch ein späteres
:ordsetfocus()
oder :gotop()
ohnehin ein neues SELECT nötig
SELECT * FROM <table> ORDER BY ....
Jetzt wird SELECT komplett neu ausgeführt.
Ist ein :ordCondSet() gesetzt, wird dies als WHERE Klausel verwendet
SELECT * FROM <table> WHERE ... ORDER BY ....
SELECT * from <table> WHERE ... ORDER BY ...
Die ORDER BY Anweisung ist noch bekannt.
dbTable:append()
dbTable:KUNDENNAME := "neuer Kunde"
dbTable:Commit()
INSERT INTO <table> (<fieldlist>) values (<valuelist>);
dbTable:Rlock(()
dbTable:KUNDENNAME := "neuer Kunde"
dbTable:Commit()
Alle Spaltenzuweisungen werden gepuffert und erst beim Commit einmalig komplett geschrieben:
UPDATE <table> SET <field1> = <value1>,...
WHERE ID = <primarykey>
ein Primarykey ist dazu unerlässlich!
(was ja gegeben ist)
DELETE FROM <table> WHERE ID =<primarykey>
Wie schon beim UPDATE ist ein Primarykey Vorraussetzung.
:SetAOF()
:ordSetFocus()
:OpenServer()
:Seek()
:Append()
INDEX.ADT
PQ2sql
SELECT ...
INSERT ...
WHERE ...
UPDATE ...
ORDER BY ...
Index.ADT
- ermöglicht, Suchausdrücke in native Werte zu zerlegen:
Metadaten werden durch ordsetfocus gesetzt und dann aufgelöst
STR(KUNDEN_NR,6)+DTOS(DATUM)
dbTable:seek(cKey)
=> SELECT * FROM <table> WHERE kunden_nr = val(left(cKey,6))
AND datum = PQdate(stod(substring(cKey,7)))
ORDER BY kunden_nr, datum
oder
=> dbTable:locate({ |db| db:kunden_nr = val(left(cKey,6)) .and.
db:datum = stod(substring(cKey,7))})
Kann 2 verschiedene Aufgaben haben:
Variante 1: einen Satz innerhalb eines Resultset suchen und ab dort weiter anzeigen.
Variante 2: Fremdschlüssel suchen
(Offensichtlich meist durch :SetRelation() implementiert)
Suche in einer Tabelle
:opentable
:ordsetfocus
:seek("Muster")
:show() oder
:Browse()
Hier gibt es nur die Lösung mittels :locate zu suchen,
oder bei großen Datenmengen eine Suche über intelligentes Positionieren und anschließend :locate zu verwenden
Bei geschätzt Datenmengen < 500 Sätze ist ein simples Skip am schnellsten.
Ansonst wird durch ein goto(lastrec()/2) in die Mitte der sortierten (!) Tabelle gesprungen und rekursiv in eine der beiden Teilmengen bis der Satz gefunden wurde.
positioniertes Suchen
Ein einfaches Select gibt einen oder mehrere Sätze zurück. Trifft zu, wenn ein Fremdschlüssel gesucht wird oder eine Teilmenge, z.B. alle Auftragspositionen zu einem Aufgtrag, etc.
SELECT ... WHERE ...
:SetRelation()
Ähnlich wie beim Seek wird ein
SELECT ... WHERE ...
ausgeführt. Dadurch erfolgt automatisch die Synchronisation.
Dies muss in den Skip Methoden erfolgen.
PQ2sql
SQL
PQclass++
C-API
PostgreSQL
Basiert auf den C-API Funktionen von PostgreSQL für die direkte Kommunikation.
Schneller gehts nicht.
PQclass++ ist ein DS-Datasoft Produkt und bereits im Einsatz.
Erzeugt Dictionary- und Tabellenobjekte analog AdsClass++.
PQ2sql
SqlXppClass++
SqlExpress
ODBC
MS-SQL Server
- PQclass für direktes Arbeiten mit "intelligentem" SQL
- SELECT ... JOIN ... UNION
neue Methoden für schnelle Abfragen:
- :fetchRow => einen Satz abfragen, dataobject()
- :fetchRows => mehrere Sätze abfragen,
Array mit dataobject()
- :fetchValue => einen Wert abfragen, nativer Wert
Einbindung von SQL Datenbank Features:
- Triggers für business logic
(Vorraussetzung für WEB Anbindung)
Ein JOIN ersetzt :SetRelation und ermöglicht zudem eine Sortierung oder Filterung auf Felder einer Fremdtabelle.
Never ending story ...