Seite 1 von 1

Filter für Query

Verfasst: Di, 03. Sep 2013 3:26
von AUGE_OHR
hi,

für DBF habe ich eine Routine um "Filter" zusammenzustellen.

Diese hab ich für SQL umgeschrieben und ein Problem beim "ausprobieren".

Code: Alles auswählen

   bSaveError := ERRORBLOCK()
   ERRORBLOCK( { | e | BREAK( e ) } )
   BEGIN SEQUENCE

      bBlock := "{|| " + cText + " }"
      //
      // da es keine DBE ist
      // erkennt er kein Field
      // und meint die Variable
      // wäre unbekannt
      //
      lret := EVAL( &( bBlock ) )

   RECOVER USING oError
      ERRORBLOCK( bSaveError )
   END SEQUENCE
   ERRORBLOCK( bSaveError )
wenn ich eine aktive DBF habe "erkennt" er ja die Feld Namen ( auch ohne Alias )

Code: Alles auswählen

cText := "artnr > '2000' .AND. artnr < '2010'"
bBlock := "{|| " + cText + " }"
aber bei "native"*** PostgreSQL Zugriff meint Xbase++ das Field "artnr" wäre eine Variabel :(
*** NICHT per pgDBE

Der Text String für PostgreSQL sieht "fertig" so aus ( nach dem WHERE )

Code: Alles auswählen

SELECT a.artnr,a.artikel FROM artikel AS a WHERE
a.artnr > '2000' AND a.artnr < '2010'
Frage : wie kann ich eine WHERE Bedingung prüfen damit kein Syntax Fehler entsteht ?

Re: Filter für Query

Verfasst: Di, 03. Sep 2013 4:48
von georg
Hallo, Jimmy -


so ganz verstehe ich Deine Frage nicht, aber:

Code: Alles auswählen

bBlock := {|x| x}
lRet := Eval(bBlock, cText)

Re: Filter für Query

Verfasst: Di, 03. Sep 2013 5:08
von AUGE_OHR
hi,
georg hat geschrieben:

Code: Alles auswählen

bBlock := {|x| x}
lRet := Eval(bBlock, cText)
hm ... das gibt mit dann cText zurück ... hm
angenommen ich würde mit "(" arbeiten dann müsste ich ja auch ")" haben ... so was will ich "prüfen" ob es beim evaluieren einen Fehler gibt.

Re: Filter für Query

Verfasst: Di, 03. Sep 2013 6:53
von georg
Hallo, Jimmy -


Deine Frage sah so aus:

Code: Alles auswählen

bBlock := "{|| " + cText + " }"
      //
      // da es keine DBE ist
      // erkennt er kein Field
      // und meint die Variable
      // wäre unbekannt
      //
      lret := EVAL( &( bBlock ) )
Genau das setzt mein Beispiel um. Daher mein "Vorwort", dass ich Deine Frage nicht richtig verstehe.

Denn auch Dein "das würde ich gerne wissen" als Inhalt von cText führt zum gleichen Problem in Deinem Code (vorausgesetzt, cText wäre eine PUBLIC/PRIVATE Variable).

Re: Filter für Query

Verfasst: Di, 03. Sep 2013 20:45
von AUGE_OHR
georg hat geschrieben:Daher mein "Vorwort", dass ich Deine Frage nicht richtig verstehe.
Du hast Recht ... ich muss ein wenig mehr erzählen was ich machen will.
georg hat geschrieben:Denn auch Dein "das würde ich gerne wissen" als Inhalt von cText führt zum gleichen Problem in Deinem Code (vorausgesetzt, cText wäre eine PUBLIC/PRIVATE Variable).
der Code war ursprünglich für DBF Felder gedacht welchen ich nun für PostgreSQL upgraden möchte.

Wenn man pgAdmin3.EXE startet gibt es einen Button SQL wo sich ein neues Fenster öffnet.
im oberen Teil gibt es ein "Eingabe" Feld ( MLE ) und darunter ein "Ausgabe" Feld.
nachdem ich eine SQL Query eingegeben habe "prüfe" ich die mit F5 und sehe ggf. eine Meldung "wo" ein Problem auftaucht.

ich will nun so etwas bei PGU.EXE, was "native" per libpq.dll zugreift, ebenfalls einbauen.

Re: Filter für Query

Verfasst: Mi, 04. Sep 2013 6:45
von georg
Hallo, Jimmy -


eine Möglichkeit wäre es, ein EXPLAIN SELECT ... durchzuführen und die Rückmeldung auszuwerten, wenn es Dir darum geht, den Inhalt der WHERE Clause zu prüfen.

Re: Filter für Query

Verfasst: Do, 05. Sep 2013 3:00
von AUGE_OHR
georg hat geschrieben:eine Möglichkeit wäre es, ein EXPLAIN SELECT ... durchzuführen und die Rückmeldung auszuwerten, wenn es Dir darum geht, den Inhalt der WHERE Clause zu prüfen.
Ja, zu einer ähnlichen Erkenntnis bin ich auch gekommen.
wenn ich eine Query an den PostgreSQL Server abschicke bekomme ich ja eine Fehlermeldung wenn was nicht stimmt. Ich muss diese also nur "abfragen" und dann auswerten "wo" er meckert.

aber trotzdem noch mal zur Frage : dynamisches Anlegen von Variablen.

Code: Alles auswählen

Variablen zur Laufzeit erzeugen 
Mit dem Makro-Operator ist es möglich, Variablen erst zur Laufzeit eines Programms dynamisch zu erzeugen, deren Name bzw. Symbol bei der Programmierung einer Applikation nicht bekannt ist. Dies wird in dem folgenden Beispiel demonstriert: 

      cVarName := "cPrivate" 
      ? Type("cPrivate")                      // Ergebnis: U 
       PRIVATE &cVarName := "Xbase++" 
       ? cVarName                              // Ergebnis: cPrivate 
      ? &cVarName                             // Ergebnis: Xbase++ 
      ? Type("cPrivate")                      // Ergebnis: C 
      ? cPrivate                              // Ergebnis: Xbase++ 

Ein Anwendungsbereich für eine solche Vorgehensweise ist etwa die Programmierung eines Befehlszeilen-Interpreters mit Xbase++. 
und dazu dies

Code: Alles auswählen

PROCEDURE MAIN
      cVarName := "cPrivate"
      ? Type("cPrivate")                      // Ergebnis: U
PRIVATE &cVarName := "Xbase++"
      ? cVarName                              // Ergebnis: cPrivate
      ? &cVarName                             // Ergebnis: Xbase++
   ? "MEMVAR_PRIVATE",IsMemvar(cVarName,MEMVAR_PRIVATE)
   ? "MEMVAR_PUBLIC ",IsMemvar(cVarName,MEMVAR_PUBLIC )
      ? Type("cPrivate")                      // Ergebnis: C
      ? cPrivate                              // Ergebnis: Xbase++
   ? "MEMVAR_PRIVATE",IsMemvar(cPrivate,MEMVAR_PRIVATE)
   ? "MEMVAR_PUBLIC ",IsMemvar(cPrivate,MEMVAR_PUBLIC )
   WAIT
RETURN
ich bekomme aber nur beim ersten IsMemvar() ein .T. :?:

Re: Filter für Query

Verfasst: Do, 05. Sep 2013 6:47
von georg
AUGE_OHR hat geschrieben:

Code: Alles auswählen

   ? "MEMVAR_PRIVATE",IsMemvar(cVarName,MEMVAR_PRIVATE)
   ? "MEMVAR_PUBLIC ",IsMemvar(cVarName,MEMVAR_PUBLIC )
      ? Type("cPrivate")                      // Ergebnis: C
      ? cPrivate                              // Ergebnis: Xbase++
   ? "MEMVAR_PRIVATE",IsMemvar(cPrivate,MEMVAR_PRIVATE)
   ? "MEMVAR_PUBLIC ",IsMemvar(cPrivate,MEMVAR_PUBLIC )
ich bekomme aber nur beim ersten IsMemvar() ein .T. :?:
Hallo, Jimmy -


das wundert mich nicht. IsMemvar() fragt ja explizit nach dem Typ, und bei der ersten Abfrage wird auf PRIVATE, bei der zweiten auf PUBLIC geprüft. Und da kann nur einer von beiden Tests erfolgreich sein, denke ich.

Re: Filter für Query

Verfasst: Sa, 07. Sep 2013 1:31
von AUGE_OHR
hi,
georg hat geschrieben:Und da kann nur einer von beiden Tests erfolgreich sein, denke ich.
YUP ... JNNN ... mich "verwirrt" nun 3 und 4 was cPrivate betrifft ...

ich hab cPrivate (und cVarName) ja nicht als Variable definiert.

Code: Alles auswählen

cVarName := "cPrivate"
cPrivate steckt als String "in" der Variable cVarName.
wenn kein Compiler Schalter gesetzt ist wird cVarName als Memvar Type PRIVATE angesehen

Code: Alles auswählen

? cPrivate   // Ergebnis: Xbase++
was ist das nun cPrivate ...
mir ist schon klar das ich mit dem Macro

Code: Alles auswählen

? &cVarName  // Ergebnis: Xbase++
das selbe erreiche. ist also cPrivate jetzt das Macro ?

aber wie bekomme ich cPrivate nun in einen Codeblock ?
nun dachte ich an so was

Code: Alles auswählen

*      cText := "{ || "+ cPrivate + "}"
*      cText := "{ || "+ &cVarName + "}"
      cText := "{ || "+ cVarName + "}"

      BBlock := &(cText)
   ?  VALType( BBlock )
   ?  EVAL( BBlock )
aber leider geht nur die letzte ...

Re: Filter für Query

Verfasst: Sa, 07. Sep 2013 10:12
von georg
Guten Morgen, Jimmy -


Dein Code bringt die korrekten Ergebnisse.

Zu dem Zeitpunkt, an dem die beiden späteren Abfragen erfolgen, haben wir folgende Variablen im Programm definiert:

Code: Alles auswählen

<Private>   cPrivate C: "Xbase++"
<Private>   cVarName C: "cPrivate"
Jetzt wird folgender Code ausgeführt:

Code: Alles auswählen

? "MEMVAR_PRIVATE",IsMemvar(cPrivate,MEMVAR_PRIVATE)
Geprüft wird laut Dokumentation der INHALT des ersten Parameters. Der erste Parameter ist cPrivate. Der INHALT von cPrivate ist ... "Xbase++".

Es gibt weder eine PRIVATE, noch eine PUBLIC Variable, die Xbase++ heisst. Korrektes Ergebnis ist als FALSE, weil gibt es nicht.
<cVarName> is a character string containing the symbolic identifier of a dynamic memory variable.
Du kannst das Ganze prüfen, indem Du aus

Code: Alles auswählen

PRIVATE &cVarName := "Xbase++"

Code: Alles auswählen

PUBLIC &cVarName := "Xbase++"
machst. Es wird dann in den ersten beiden Prüfungen FALSE und TRUE ausgegeben, was beweist, dass nicht cVarName geprüft wird, sondern der Inhalt von cVarName (denn cVarName ist ja immer noch PRIVATE, während cPrivate nun eine PUBLIC Variable ist.