SQL Abfrage mit dem Builder



  • Hallo,

    Vielen Dank für die Hilfe, aber so ganz habe ich das noch nicht geblickt!

    Wenn ich mein Startdatum mit StrToDateTime umwandle dann ensteht doch je nach
    Datum eine Fliesskommazahl! z.B, 01.01.2005 32448.32 (die Zahl ist frei erfunden)
    Diese packe ich nun in meine SQL-Abfrage oder ???
    Oracle sieht doch dann die Zahl und nicht das Datum.

    Nachdem ich nun Code von Alexander Kempf übernommen habe meckert die DB einen Indexfehler ORA-0091:invalid character an.

    Liegt das vielleicht an obigem Problem ??

    Gruss
    Difu



  • DiFu schrieb:

    Oracle sieht doch dann die Zahl und nicht das Datum.

    Deswegen ja die Parameter und AsDateTime. Damit überlässt man den DB-Komponenten die korrekte Umwandlung.

    DiFu schrieb:

    (...)meckert die DB einen Indexfehler ORA-0091:invalid character an.

    Die entsprechende Fehlermeldung dazu lautet:

    ORA-00091: LARGE_POOL_SIZE must be at least string
    Cause: The value of LARGE_POOL_SIZE is below the minimum size.
    Action: Increase the value of LARGE_POOL_SIZE past the minimum size.

    Was das allerdings bedeutet, weiß ich nicht.

    Vielleicht zeigst Du noch mal den überarbeiteten Code.
    Hast Du mal versucht, das Statement direkt auf die DB loszulassen (z.B. mit SQL-Explorer)?

    Gruß,

    Alexander



  • Die Abfrage in meiner Funktion habe ich zuerst im SQL-Worksheet erstellt.
    Da läuft die Abfrage unter Oracle einwandfrei.
    Ich wollte dann nur die veränderbaren Variablen wie Datum und TPP einbauen. (die sind in der Anwendung wählbar)
    Das ganze liegt nur am Datum, da ohne Datum die Abfrage funktioniert. Ich brauche aber das Sch.... Datum, da der User die Statistik in
    einem bestimmten Datumsbereich wählen soll.

    AnsiString starttime="01.05.2004 09:00:00";//zu Testzwecken
    AnsiString endtime="04.05.2004 09:00:00";//zu Testzwecken
    Form1->Query1->SQL->Add(get_sql_for_auswahl_tpp(Form1->startdate,Form1->enddate));
    Form1->Query1->Prepare();
    Form1->Query1->ParamByName("PTPP_BEZEICHNUNG")->AsString = Form1->ComboTPP->Items->Strings[Form1->ComboTPP->ItemIndex];
    Form1->Query1->ParamByName("PFROM_DATE")->AsDateTime = StrToDateTime(starttime);
    Form1->Query1->ParamByName("PTO_DATE")->AsDateTime = StrToDateTime(endtime);
    Form1->Query1->Open(); //hier setzt es dann aus und die Fehlermeldung erscheint
    Form1->Query1->First(); 
    
    AnsiString get_sql_for_auswahl_tpp()
    {
     AnsiString sql_code="select sum(s.delta_t),m.ag_key from stoerung s join maschinendaten m on m.maschinen_id=s.maschinen_id join stoppgrund st on st.stoppgrund_id=s.stoppgrund_id join tpp t on t.tpp_id=st.tpp_id";
     sql_code +=" where tpp_bezeichnung= :PTPP_BEZEICHNUNG";
     sql_code +=" and start_date between :PFROM_DATE and :PTO_DATE group by m.ag_key;";
     return sql_code;
    }
    

    Habe als Datum schon alle Formate im C-Code ausprobiert aber nix hilft!!



  • Du könntest zu Testzwecken anstatt von AnsiString-Variablen TDateTime-Variablen verwenden. Vielleicht könnte auch der Benutzer aus
    einem DateTimePicker auswählen (oder kann er das etwa?).

    Zum Testen könntest Du z.B. mal das hier ausprobieren:

    TDateTime starttime = EncodeDateTime(2004, 5, 1, 9, 0, 0, 0); // oder u.U. mal Now() verwenden
    TDateTime endtime = EncodeDateTime(2004, 5, 4, 9, 0, 0, 0);
    // Eine gute Idee ist es sicherlich auch, vorher das alte Statement zu löschen:
    Form1->Query1->SQL->Clear();
    Form1->Query1->SQL->Add(get_sql_for_auswahl_tpp()); // Argumente gelöscht
    Form1->Query1->Prepare();
    Form1->Query1->ParamByName("PTPP_BEZEICHNUNG")->AsString = "abc";
    Form1->Query1->ParamByName("PFROM_DATE")->AsDateTime = starttime;
    Form1->Query1->ParamByName("PTO_DATE")->AsDateTime = endtime;
    Form1->Query1->Open();
    

    Du hattest in dem Code-Beispiel noch den Aufruf von get_sql_for_auswahl_tpp() noch die Argumente drinstehen, was ich in meinem Beispiel
    natürlich auch schon falsch hatte. So hätte das gar nicht kompiliert werden dürfen?! Abgesehen davon ist die Methode in der Form relativ
    überflüssig. Eine gebräuchliche AnsiString-Variable würde so genügen.

    Schau auch mal im Debugger, welche Werte die einzelnen Variablen haben; auch die Parameter.

    Ist eigentlich das Feld start_date auf der Datenbank vom Typ DATE?

    Gruß,

    Alexander



  • Also irgendwie passt das mit der Fehlermeldung nicht. Könnte es nicht eventuell diese Fehlernummer sein? Paßt besser zur Fehlermeldung:

    ORA-00911: invalid character

    Cause: Special characters are valid only in certain places. If special characters other than $, _, and # are used in a name and the name is not enclosed in double quotation marks ("), this message will be issued. One exception to this rule is for database names; in this case, double quotes are stripped out and ignored.
    Action: Remove the invalid character from the statement or enclose the object name in double quotation marks.



  • Hallo
    leider kennt mein Builder (Version5) die Methode EncodeToDateTime nicht.

    Alexander Kempf schrieb:

    Abgesehen davon ist die Methode in der Form relativ
    überflüssig. Ist eigentlich das Feld start_date auf der Datenbank vom Typ DATE?

    Natürlich hast du Recht, jetzt in dieser Form ist meine Funktion nicht sehr sinnvoll,
    aber es war etwas geplant. Ich hatte nicht mit solchen Problemen beim Datum gerechnet.
    In der Datenbank sind die beiden Werte definitiv vom Typ Date.
    Habe eben nochmal im SQL-Skript nachgeschaut. Das komische ist nur das die Abfrage unter
    Oracle läuft. Muss ich vielleicht vor jedem Zugriff das Datumsformat vorwegschicken.
    Ich rufe im Moment ein SQL-Befehl direkt unter Oracle auf, um das Format bekannt zu machen??

    Gruss
    Difu

    Ich glaube, ich muss bis nach den Ferien warten um meinen Projektleiter mal zu fragen.



  • Zeig doch einfach mal ein bisschen mehr Quelltext. Ich kann eigentlich nicht verstehen, warum das Statement nicht funktionieren sollte.
    Auch ich arbeite mit Oracele-Datenbanken und DATE-Feldern und nach anfänglichen Problemen funktioniert das jetzt ganz gut.
    Die Schwierigkeiten, von denen Du berichtest, habe ich aber noch nie gehabt.

    Hast Du Dir auch mal den SQL-String (TQuery::SQL::Text) im Debugger angeschaut. Ich versuche dann auch oft, den String rauszukopieren
    und direkt auf die Datenbank loszulassen.

    An welcher Stelle im Programm schickst Du "alter session set nls_date_format='dd.mm.yyyy hh24:mi:ss';" ab?

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    An welcher Stelle im Programm schickst Du "alter session set nls_date_format='dd.mm.yyyy hh24:mi:ss';" ab?

    Das starte ich zunächst manuell in meinem Oracle-SQL-Worksheet um das Format bekannt zu geben. Sollte ich das besser
    in meinem Programm starten ??
    Ich könnte ja mal mein Script zur DB posten, ich weis allerdings nicht ob das hier ins Forum gehört??
    Welcher Code von meinem Prog. könnte den noch helfen ??

    Gruss
    Difu



  • DiFu schrieb:

    Das starte ich zunächst manuell in meinem Oracle-SQL-Worksheet um das Format bekannt zu geben. Sollte ich das besser
    in meinem Programm starten ??

    Natürlich. Du änderst damit ja nur die Einstellungen der Session und die ist natürlich eine andere als in Deinem Oracle-SQL-Worksheet (was
    immer das ist).

    DiFu schrieb:

    Ich könnte ja mal mein Script zur DB posten, ich weis allerdings nicht ob das hier ins Forum gehört??

    Ich vermute, dass das nicht besonders hilfreich ist, zumal das Skript nach Deinen Aussagen ja funktioniert.

    DiFu schrieb:

    Welcher Code von meinem Prog. könnte den noch helfen ??

    Irgendwas, das den Programmfluss besser zeigt. Bisher hast Du nur Code gezeigt, der mehr oder weniger "in der Luft hing".

    Was Du auf jeden Fall mal versuchen solltest, ist, ein ganz einfaches Statement aus Deinem Code heraus aufzurufen, um sicherzustellen,
    dass Du keinen Riesenbock drinhast. Also irgendwas wie "SELECT * FROM tabellexyz". Wenn das schon nicht klappt, hast Du ein prinzipielles
    Problem. Gut wäre auch das Statement, das in Deinem Skript funktioniert, mal statisch im Programm einzufügen - ohne das Statement selbst
    zusammenzubasteln und ohne Parameter.

    Gruß,

    Alexander



  • Ich habe jetzt die Lösung für mein obiges Problem gefunden.
    Ich erweitere meine Abfrage einfach mit dem Datumsformat (unterstrichen).

    [cpp]
    AnsiString get_sql_for_auswahl_tpp(AnsiString startdate,AnsiString enddate)
    {
    AnsiString sql_code=NULL;
    sql_code="select sum(s.delta_t),m.ag_key from stoerung s join maschinendaten
    on m.maschinen_id=s.maschinen_id join stoppgrund st on st.stoppgrund_id=s.stoppgrund_id join tpp t on t.tpp_id=st.tpp_id";
    sql_code +=" where tpp_bezeichnung='";
    sql_code +=Form1->ComboTPP->Items->Strings[Form1->ComboTPP->ItemIndex];
    sql_code +="' and (start_date between to_date('";
    sql_code +="01.05.2004 09:00:00','dd.mm.yyyy hh24:mi:ss'";
    sql_code +=") and to_date('";
    sql_code +="31.05.2004 09:00:00','dd.mm.yyyy hh24:mi:ss'";
    sql_code +="')) group by m.ag_key;";
    return sql_code;
    }
    [/cpp]

    Gruss Difu

    😃 😃


Anmelden zum Antworten