| |
|
|
- Seite 1 - |
|
RGH | Getestet mit Profan2cpp 1.6b:
Wenn bei InStr() ein dritter Parameter (Offset) mit angegeben wird, wird dieser offensichtlich um 1 falsch interpretiert. Folgendes Testprogramm macht es deutlich:
declare split%, pos%, satz$, text$
text$ = Hugo was here. Hugo was here.
print instr(Hugo, text$) In XProfan und Prf2Cpp gleich: 1 - 1
print instr(Hugo, text$,1) In XProfan und Prf2Cpp gleich: 1 - 1
print instr(Hugo, text$,16) In XProfan und Prf2Cpp gleich: 16 - 16
print instr(Hugo, text$,17) In XProfan und Prf2Cpp UNgleich: 0 - 16
waitinput
end
In XProfan liefert die letzte Zeile korrekterweise den Wert 0, da ab Position 17 (das u im 2. Hugo) der gesuchte String Hugo ja nicht mehr vorkommt. Prf2Cpp liefert hingegen den Wert 16, der definitiv vor der Stelle liegt, ab der gesucht wird.
Gruß Roland (ansonsten von Profan2CPP begeistert, da sich damit ohne jeden Aufwand nahezu alle Programme per Knopfdruck deutlich beschleunigen lassen) |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 18.12.2007 ▲ |
|
|
|
|
| |
|
- Seite 1 - |
|
RGH | Sebastian König
Zu deren Erscheinungstermin kann ich leider noch nichts sagen
Es eilt nicht. Wenn man es mal rausgefunden hat kann man die Abfrage entsprechend modifizieren. Wenn das Ergebnis von Instr() größer als die Länge des Strings ist, ist es eben als 0 zu werten.
Allerdings ist mir heute (ich beschleunige in der Firma gerade ein von mir in XProfan geschriebenes Statistik-Programm, daß über 23 Millionen Datensätze aus beinahe 3000 Textdateien einliest, bearbeitet und in eine MySQL-Datenbank des Rechenzentrums schreibt) noch ein weiterer Fehler aufgefallen:
2006-12-18 > 2005-07-16 13:34:26 ergibt 0 (falsch), obwohl der Stringvergleich 1 (wahr) ergeben müßte. Wenn ich den ersten String nun um 9 Leerzeichen auf die gleiche Länge des zweiten Strings bringe, stimmt das Ergebnis des Vergleichs.
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 18.12.2007 ▲ |
|
|
|
|
Sebastian König | RGH
Es eilt nicht. Wenn man es mal rausgefunden hat kann man die Abfrage entsprechend modifizieren. Wenn das Ergebnis von Instr() größer als die Länge des Strings ist, ist es eben als 0 zu werten.
Nicht ganz: Es ist im Moment vielmehr so, dass (Startposition - 1) zurückgegeben wird, falls der String nicht gefunden wird. Ich weiß nicht, warum und wann ich diesen Fehler eingebaut habe... wahrscheinlich ist es bisher nicht aufgefallen, da der Default für die Startposition einfach 1 ist und dann korrekt 1 - 1 = 0 zurückgegeben wird...
RGH
Allerdings ist mir heute (ich beschleunige in der Firma gerade ein von mir in XProfan geschriebenes Statistik-Programm, daß über 23 Millionen Datensätze aus beinahe 3000 Textdateien einliest, bearbeitet und in eine MySQL-Datenbank des Rechenzentrums schreibt) noch ein weiterer Fehler aufgefallen:
2006-12-18 > 2005-07-16 13:34:26 ergibt 0 (falsch), obwohl der Stringvergleich 1 (wahr) ergeben müßte. Wenn ich den ersten String nun um 9 Leerzeichen auf die gleiche Länge des zweiten Strings bringe, stimmt das Ergebnis des Vergleichs.
Hmm. Hier habe ich offenbar das Verhalten des Stringsvergleich in XProfan offenbar nicht genau genug analysiert... der Code, der bei der >-Operation letztlich aufgerufen wird, sieht im Moment so aus (aus pstring.h):
D.h. vor dem lexikographischen Vergleich wird erstmal geprüft, ob nicht der eine schon länger oder kürzer als der andere ist. Wenn das in XProfan nicht so ist, muss ich das wohl ändern... ich melde mich voraussichtlich morgen mal mit einer neuen Version
MfG
Sebastian |
|
|
| |
|
|
|
RGH | Sebastian König
vor dem lexikographischen Vergleich wird erstmal geprüft, ob nicht der eine schon länger oder kürzer als der andere ist. Wenn das in XProfan nicht so ist, muss ich das wohl ändern... ich melde mich voraussichtlich morgen mal mit einer neuen Version
Nein, das ist in XProfan (und Basic und Delphi ...) nicht so. Die Länge des Strings tut nichts zur Sache. Ein Leerstring ist der Kleinstmögliche String, ansonsten zählen nur die Ansicodes der Zeichen. < chr$(0) < chr$(1) ... < ... text < text1 ... aber text > texa1
Kurz: Ich denke, du mußt die Längenüberprüfung einfach weglassen.
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 18.12.2007 ▲ |
|
|
|
|
Sebastian König | RGH
Kurz: Ich denke, du mußt die Längenüberprüfung einfach weglassen.
Ja, so mache ich es jetzt - nur für den Fall, dass einer der beiden Strings leer ist, musste ich noch eine Zusatz-Abfrage einbauen.
Eine korrigierte Version geht gleich per eMail an Dich raus .
MfG
Sebastian |
|
|
| |
|
|
|
RGH | Sebastian König
Eine korrigierte Version geht gleich per eMail an Dich raus .
Super! Danke!
Die beiden Probleme sind weg. Aber ich bin auf ein weiteres gestoßen: Embedded SQL scheint nicht zu funktionieren. (Kann es sein, dass es defaultmäßig ausgeschaltet ist?)
if prav_db% = 1
sql$ = insert into prav values (:id_db$,:timestamp_db$,:datum_db$,:berater_db$,:kunde_db$,:sek_db$,:modul_db$,:aktion_db$,:online_db$,:dauer_db&,:moddauer_db&,:berdauer_db&)
sqlexec sql$, 2
else
sql$ = insert into fim values (:id_db$,:timestamp_db$,:datum_db$,:berater_db$,:kunde_db$,:sek_db$,:modul_db$,:aktion_db$,:online_db$,:dauer_db&,:moddauer_db&,:berdauer_db&)
sqlexec sql$, 2
endif
Hier meldet sich der ODBC-Treiber mit der Meldung, dass die SQL-syntax near values (:id_db$;:time... nicht in Ordnung ist. Das dürfte bei eingeschaltetem embedded SQL so nie beim ODBC-Treiber ankommen.
Gruß Roland
(Sorry, dass ich dieses Thread für die Meldung missbrauche, aber vom Arbeitsplatz kann/darf ich keine privaten eMails verschicken.) |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 20.12.2007 ▲ |
|
|
|
|
Sebastian König | RGH
Super! Danke!
Die beiden Probleme sind weg.
Ah, super - das ist schonmal gut!
RGH
Aber ich bin auf ein weiteres gestoßen: Embedded SQL scheint nicht zu funktionieren. (Kann es sein, dass es defaultmäßig ausgeschaltet ist?)
if prav_db% = 1
sql$ = insert into prav values (:id_db$,:timestamp_db$,:datum_db$,:berater_db$,:kunde_db$,:sek_db$,:modul_db$,:aktion_db$,:online_db$,:dauer_db&,:moddauer_db&,:berdauer_db&)
sqlexec sql$, 2
else
sql$ = insert into fim values (:id_db$,:timestamp_db$,:datum_db$,:berater_db$,:kunde_db$,:sek_db$,:modul_db$,:aktion_db$,:online_db$,:dauer_db&,:moddauer_db&,:berdauer_db&)
sqlexec sql$, 2
endif
Hier meldet sich der ODBC-Treiber mit der Meldung, dass die SQL-syntax near values (:id_db$;:time... nicht in Ordnung ist. Das dürfte bei eingeschaltetem embedded SQL so nie beim ODBC-Treiber ankommen.
Eigentlich sollte es eingeschaltet sein, wenn es nicht explizit mit der Kommandozeilen-Option -noemsql deaktiviert wird. Ich sehe mal nach, was da schiefläuft und melde mich wieder.
MfG
Sebastian |
|
|
| |
|
|
|
Sebastian König | Ok, die Ursache des Problems war recht schnell gefunden: Profan2Cpp berücksichtigt embedded SQL nur direkt in SQLExec-Befehlen! Ich war davon ausgegangen, dass das auch in XProfan so ist...
Ist es tatsächlich so, dass es in XProfan mit beliebigen Literalen funktioniert?
MfG
Sebastian
Nachtrag: Ich verstehe auch die Hilfe so, dass es nur bei SQLExec funktioniert:
XProfan-Hilfe
Bei SQLExec können ab XProfan 9 direkt Variablen, wie in embedded SQL bei C++ bzw. Java, eingesetzt werden. Einfach einen Doppelpunkt vor die Variable: (...)
Mein Vermutung (bzw. Befürchtung) ist, dass XProfan den String dynamisch untersucht und ggf. die Variablennamen ersetzt. In Profan2Cpp geht dies leider konzeptionell nicht - der String muss zum Zeitpunkt der Übersetzung aufgelöst werden.... |
|
|
| |
|
|
|
RGH | Hallo Sebastian,
embedded SQL fubktioniert in der Tat nur bei SQLExec und nicht bei beliebigen Literalen.
(Ich hatte in der Tat auch mit der Version für beliebige Literale experimentiert, dafür aber wegen der einfachen Hochkommas, die einen Stringwert einschließen, keine sinnvolle Anwendung gefunden.)
Beim obigen Beispiel funktioniert das intern also so: Im String SQL$ steht also immer das, was auch im Programm steht, also z.B. where id = :id$. Erst der SQLExec-Befehl selbst untersucht den ihm übergebenen String auf eingebettete Variablen und ersetzt diese dann durch ihren Inhalt. Würde in id$ also z.B. der Wert session5A6BC95601 stehen, würde aus :id$ dann also where id = session5A6BC95601 werden. Die Auflösung kann natürlich erst zur Laufzeit geschehen, auch in der Runtime.
Ok, ich weiß, dass das die Sache für Dich nicht einfacher macht. Möglicherweise mußt Du embedded SQL tatsächlich auf das direkte Literal hinter SQLExec beschränken. Aber leider funktioniert das derzeit auch nicht. Wenn ich das mit den obigen SQL$-Strings mache ...
if prav_db% = 1
sqlexec insert into prav values (:id_db$,:timestamp_db$,:datum_db$,:berater_db$,:kunde_db$,:sek_db$,:modul_db$,:aktion_db$,:online_db$,:dauer_db&,:moddauer_db&,:berdauer_db&), 2
else
sqlexec insert into fim values (:id_db$,:timestamp_db$,:datum_db$,:berater_db$,:kunde_db$,:sek_db$,:modul_db$,:aktion_db$,:online_db$,:dauer_db&,:moddauer_db&,:berdauer_db&), 2
endif
... stürzt der Prof2CPP mit einer Schutzverletzung ab. (Bei kürzeren Zeilen läuft er aber durch.)
Aber bitte jetzt keine Hektik, Sebastian. Ich habe mein Programm jetzt umgeschrieben und auf embedded SQL verzichtet (da sehen die Zeilen halt dann etwas komplizierter aus: ... values ( + id$ + + ...) und es scheint jetzt zu funktionieren. Aus dem mehrtägigen Statistikjob ist jetzt hoffentlich wieder eine Sache geworden, die über Nacht durchläuft. (Man läßt Vorgesetzte halt nicht gerne lange warten ... ;) )
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 20.12.2007 ▲ |
|
|
|
| |
|
- Seite 2 - |
|
|
| Ich glaube Sebastians mögliches Problem im Bezug auf die Herstellung selbiger Funktionalität hat eher die Ursache das er mit Listen arbeiten müsste um auf Variableninhalte zugreifen zu können welche der Funktion selbst garnicht bekannt sein können. Der Source wird hierbei ja nicht interpretiert und die Variablen sind im prf2cpp-Fall ja echte Variablen. Was jedoch ein einfacher Workaround für Sebastian sein könnte ist das Umschreiben solcher Literale durch seinen Präkompiler in die nicht-embed-Variante ala +vari$+. |
|
|
| |
|
|
|
RGH | iF
Was jedoch ein einfacher Workaround für Sebastian sein könnte ist das Umschreiben solcher Literale durch seinen Präkompiler in die nicht-embed-Variante ala +vari$+.
Was aber, wenn im String tatsächlich so etwas wie :hugo$ stehen soll und er nicht für SQLExec gedacht ist? (Zugegeben: Es ist eher unwahrscheinlich, aber eben nicht unmöglich.)
Ich denke, es spricht nichts dagegen, zu sagen: Prf2CPP kann embedded SQL nur, wenn, wenn es als Literal hinter SQLExec steht. Dann kann sich der geneigte Programmierer dananch richten.
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 20.12.2007 ▲ |
|
|
|
|
| RGH
Was aber, wenn im String tatsächlich so etwas wie :hugo$ stehen soll und er nicht für SQLExec gedacht ist? (Zugegeben: Es ist eher unwahrscheinlich, aber eben nicht unmöglich.)
Sollte man deshalb nicht vorsorglich die Eingaben dahingehend überprüfen? Ich glaube ich habe das XProfansche SQLEmbedded demnach noch nicht ganz kappiert - das soll hier aber nicht das Thema sein.
Was ich versuchte zu sagen ist das es eben dem Sebastian nicht möglichst ist zur Laufzeit auf den Inhalt einer Variablen zuzugreifen deren Name auch erst zur Laufzeit ermittelt/erzeugt wird ohne auf z.B. listen wie spezielle assoziative Arrays zugreifen zu müssen. Daher mein Vorschlag des Umschreibens durch den Präkompi. Wie er das löst wird er aber natürlich selbst am besten wissen - ich hab ja nur gestochert. |
|
|
| |
|
|
|
Sebastian König | iF hat das Problem genau richtig beschrieben... Das ist das, was ich mit der String muss zum Zeitpunkt der Übersetzung aufgelöst werden etwas unpräzise ausgedrückt habe.
Als Notlösung schwebt mir im Moment vor, eine Möglichkeit einzubauen, das embedded SQL temporär auch für beliebige Literale einzuschalten, am besten mit dem gleichen Konzept über spezielle Kommentare, wie ich es auch schon für Call() und External() im Zusammenhang mit der Multithread-Problematik eingebaut habe (siehe Punkt 3 unter Sonstige Features in der Profan2Cpp-Hilfe). Das hätte den Vorteil, dass man die Codes mit recht geringem Aufwand gleichzeitig zu XProfan und Profan2Cpp kompatibel machen kann.
Um das andere angesprochene Problem kümmere ich mich bei Gelegenheit - evtl. am Wochenende, da ich morgen zunächst noch an der Uni und dann den ganzen Nachmittag im Zug sein werde... Zum Glück eilt es ja nicht
MfG
Sebastian |
|
|
| |
|
|