Announcement

Collapse
No announcement yet.

SQL zu HQL

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • SQL zu HQL

    Hallo,

    ich hab volgendes problem:
    Ich hab mir eine SQL (PGSQL) Anweisungzusammen gebaut um was aus eine DB zu berechen. Funktunirt auch super. Jetzt holte ich sie im das Programm einbaun. da wirt die SQL Anweisung aber über Hibernate geschickt und das nimst nur HQL.
    Meine SQL Anweisung habt aber im FROM ein Subselect das laut HQL reference nicht im FROM unterstützt wirt.

    Kännte jemand ein weg das so umzubauen das HQL das abzeptirt?
    oder andere hinweise und vorschläge?

    Hier noch der SQL Code:

    SELECT stid,
    (((MAX(startkapital)*MAX(kapitalinvest)+SUM(summ)) *100/(MAX(startkapital)*MAX(kapitalinvest)))-100) as erg2
    FROM Strategie o, testbedingung t,
    (SELECT SUM(guvtrade) as summ,ergebnisid,MAX(strategieid) as st FROM einzeltrade, ergebnis
    WHERE einkaufszeitpunkt >= '20100801 00:00:00'
    AND einkaufszeitpunkt <= current_date
    AND ergebnis.eid = einzeltrade.ergebnisid
    AND datenart = 0/*1*/
    GROUP BY ergebnisid ) as tsum
    WHERE showranking = 'true'
    AND t.tid = o.testbedingungid
    AND o.stid = tsum.st
    GROUP BY stid
    ORDER BY erg2 DESC

    Danke für die Hilfe.
    MfG Tacco

  • #2
    a) ohne dein Klassenmodell zu kennen kann das keiner in HSQL umsetzen

    b) Die Hibernatesession kennt die Methode createSQLQuery die einen Original SQL verarbeitet
    Christian

    Comment


    • #3
      ich muss dazu sagen das ich das Projekt übergeben bekommen habe und nur erweiterungen durchfüre, daher weiß nich nicht uber die gesamte struktur bescheit. Ich hab mich auch in den zusamenhang das erste mal mit Hibernate beschäftigt.

      ich habe nach den vorbild weitergebaut und dann mein SQL String eigebaut.

      public static List<Ranking> Strategie.getRanking(){
      return entityManager().createQuery("select stid, " +
      "CAST((((MAX(startkapital)*MAX(kapitalinvest)+SUM( summ))*100/(MAX(startkapital)*MAX(kapitalinvest)))-100) as BIGINT) as erg2 " +
      "from Strategie o, testbedingung t, " +
      "(SELECT SUM(guvtrade) as summ,ergebnisid,MAX(strategieid) as st FROM einzeltrade, ergebnis " +
      "WHERE einkaufszeitpunkt >= '20100801 00:00:00' " +
      " AND einkaufszeitpunkt <= current_date " +
      " AND ergebnis.eid = einzeltrade.ergebnisid " +
      " AND datenart = 0 " +
      " GROUP BY ergebnisid) as tsum " +
      "where showranking = 'true' " +
      "AND t.tid = o.testbedingungid " +
      "AND o.stid = tsum.st " +
      "GROUP BY stid " +
      "ORDER BY erg2 DESC").getResultList();
      }

      Was jetzt die Hibernatesession betrift weiß ich nicht wo ich die finde.

      Ich habe aber jetzt mal createNativeQuery() probirt, was jetzt erstmal keine Erro in den sql mäldet. hab aber dan immer noch beim auslessen Fehler. Das könnte aber auch an der klasse des übergabetypen liegen da ich da auch noch nicht genau weiß wie die aufgebaut sein muss.

      Wenn eine bissen mehr ahnung von Hibernate hat und mir da paar tips geben könnte were ich sehr dankbar.

      MfG
      Tacco

      Comment


      • #4
        createNativeQuery nutzt man, wenn es sich um den EntityManager handelt und um eine Java EE Anwendung
        Christian

        Comment


        • #5
          Also die Query lässt sich ohne Fehler erzeugen? Das ist ja schonmal gut. Was Hibernate jetzt versucht, ist mit den Ergebnissen der Query eine Liste von Ranking Instanzen zu erzeugen. Wenn es da kracht, wäre es gut, mal die Exception zu sehen, die dann kommt.

          Allgemein muss es irgendwo ein Mapping von der Ranking-klasse in die Datenbanstruktur geben. Das geht entweder mit Annotations direkt in der Ranking Klasse oder mit einer Mapping-Datei. Üblicherweise gibt es dafür ein Mapping-Element in der hibernate.cfg.xml, das auf diese Datei verweist. Das könnte Dich auf die Spur bringen, welcher Wert im Query-Result fehlt.

          Gruß ngomo
          http://www.winfonet.eu

          Comment


          • #6
            @Christian Marquardt
            ja stimt hätte ich gelich sagen sollen ein EntityManager ist da und es ist eine Java EE Anwendung.


            @ngomo
            die SQL Anweisung leuft aus den PGServer und bring das gewünste ergebnis. und seint ich createNativeQuery benutze komt auch kein FEhler im programm der sich auf die SQL anweisung bezicht.
            das were der Fehler der aber nur auftrit wenn ich in der Ranking.jspx datein aus den variablen zugrifen möchte die das SQL ergebnis haben solten.
            Fehler:
            SCHWERWIEGEND: Servlet.service() for servlet tw threw exception
            java.lang.NumberFormatException: For input string: "max"
            at java.lang.NumberFormatException.forInputString(Num berFormatException.java:48)
            at java.lang.Integer.parseInt(Integer.java:449)
            at java.lang.Integer.parseInt(Integer.java:499)
            at javax.el.ArrayELResolver.coerce(ArrayELResolver.ja va:153)
            at javax.el.ArrayELResolver.getValue(ArrayELResolver. java:45)
            at javax.el.CompositeELResolver.getValue(CompositeELR esolver.java:54)
            at org.apache.el.parser.AstValue.getValue(AstValue.ja va:118)
            at org.apache.el.ValueExpressionImpl.getValue(ValueEx pressionImpl.java:186)
            at org.apache.jasper.runtime.PageContextImpl.propriet aryEvaluate(PageContextImpl.java:935)
            at org.apache.jsp.WEB_002dINF.views.ranking.ranking_j spx._jspx_meth_spring_005fmessage_005f0(ranking_js px.java:136)
            at org.apache.jsp.WEB_002dINF.views.ranking.ranking_j spx._jspx_meth_c_005fforEach_005f0(ranking_jspx.ja va:104)
            at org.apache.jsp.WEB_002dINF.views.ranking.ranking_j spx._jspService(ranking_jspx.java:68)
            ...

            ich weis aber nicht ob ich die Ranking Klasse die die SQL Ergebise aufnämen soll richtig gebaut habe.

            Das were die Klasse:
            package de.stqs.labs.tw.ebeans;

            import java.io.Serializable;

            public class Ranking implements Serializable{
            private int max;
            private int erg2;
            public void setMax(int max) {
            this.max = max;
            }
            public int getMax() {
            return max;
            }
            public void setErg2(int erg2) {
            this.erg2 = erg2;
            }
            public int getErg2() {
            return erg2;
            }
            }

            Das mit den Mapping schau ich mir jetzt mal an.

            Danke euch beiden schon mal für die hilfe ^-^

            MfG
            Tacco

            EDIT:
            ich hab übriges übers DEBUG rausgefunden das die richtigen werte im Mapping drin stehen. in den fall 3 mal 2 werte. (3 zeilen mit 2 spalten aus den sql abfrage wies sein soll.
            Zuletzt editiert von Tacco; 19.08.2010, 10:13.

            Comment


            • #7
              java.lang.NumberFormatException: For input string: "max"
              at java.lang.NumberFormatException.forInputString(Num berFormatException.java:48)
              at java.lang.Integer.parseInt(Integer.java:449)
              Das ist leicht, an irgendeiner Stelle Deiner Anwendung versucht er einen String in einen Integer, umzuwandeln, der keine Zahl ist (z.B. "xyz"). Wenn das Mapping korrekt ist, dürfte das eigentlich nicht passieren. Deswegen vermute ich, dass entweder die Exception garnicht beim Laden von DB-Objekten, sondern an einer andren Stelle auftritt. Oder Deine Query gibt für max keine Zahl zurück. Lass die Query mal manuell über einen SQL-Client laufen und guck Dir das Ergebnis an. Vielleicht ist max ja z.B. "NULL".

              Gruß ngomo
              http://www.winfonet.eu

              Comment


              • #8
                ja das der fehler das aussaget weiß ich auch aber ich komme nicht dahinter wieso.

                die ausgabe des Qwerys ist folgenden:

                22;13
                23;-19
                11749;-27

                erste stalte max und zweiter erg2.

                wenn ich in der Ranking.jspx erg2 oder max aufrufen möchte kommt immer der fehler.
                ich hab schon mit verschiden aufrufen probirt:

                <c:forEach var="strategie" items="${strategien}">
                <tr>
                <td class="helpBod">
                <spring:message text="${strategie.erg2}" />
                <cut value="${strategie.erg2}" />
                ${strategie.erg2}

                </td>
                </tr>
                </c:forEach

                beim DEBUGEN habe ich aber geshen das er die richtegen werte übernommen hat.
                also die ober angegeben zahlen.

                ich habe diesen forums eintrag gefunden die haben eigentlich so zimlich das gliche problem:
                http://forum.springsource.org/showthread.php?t=76985

                nur das ich die spring version 3.0.0 benutze.

                MfG Tacco

                Comment


                • #9
                  http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/c/out.html
                  Es wird ein String erwartet und kein nummerischer Typ
                  Christian

                  Comment


                  • #10
                    du meinst jetzt beim <cut value="..."/>
                    oder?

                    das ${strategie.erg2} schreibt ja nur denn Inhalt der variable in den quelltext das sollte er schon als String auffassen. und beim <cut value=" " sind die "" ja um das als String zu maskieren.

                    Ich habs aber trotzdem mal so gemacht das erg2 ein String ist. in der Ranking.java und es kommt auch als String aus den Query. aber der Fehler bleibt glich. außerdem meckert er ja max oder erg2 an und nicht 22 oder so.

                    Ich hab die funkiton mal geändert:
                    public static List<Ranking> Strategie.getRanking(){
                    List<Ranking> temp= entityManager().createNativeQuery("select stid, " +
                    "CAST((((MAX(startkapital)*MAX(kapitalinvest)+SUM( summ))*100/(MAX(startkapital)*MAX(kapitalinvest)))-100) as BIGINT) as erg2 " +
                    "from Strategie o, testbedingung t, " +
                    "(SELECT SUM(guvtrade) as summ,ergebnisid,MAX(strategieid) as st FROM einzeltrade, ergebnis " +
                    "WHERE einkaufszeitpunkt >= '20100801 00:00:00' " +
                    " AND einkaufszeitpunkt <= current_date " +
                    " AND ergebnis.eid = einzeltrade.ergebnisid " +
                    " AND datenart = 0 " +
                    " GROUP BY ergebnisid) as tsum " +
                    "where showranking = 'true' " +
                    "AND t.tid = o.testbedingungid " +
                    "AND o.stid = tsum.st " +
                    "GROUP BY stid " +
                    "ORDER BY erg2 DESC").getResultList();
                    return temp;
                    }

                    neu ist das temp. in der temp ist während des Debuggens der richtige Inhalt drin also das mit dem Ranking Objekt sollte gehen. nur dann irgendwo danach kracht es wenn es zur Anzeige kommen soll.

                    Danke für die bisherigen Bemühungen ^-^


                    MfG
                    Tacco
                    Zuletzt editiert von Tacco; 19.08.2010, 15:12.

                    Comment


                    • #11
                      So naja mitlerwiele habe ich eine lösung.

                      der aufruf vom EntityManager für das qwery leifete zwar die liste mit Obekten und den inhalten aber rigentwie hats nicht mit den typ für die Ranking klasse hingehauen. daher hab ich jetzt das Obekt manuel zu ein Rankingobekt umgebaut.

                      hier die neue Funktion:

                      public static List<Ranking> Strategie.getRanking(){
                      List temp= entityManager().createNativeQuery("select stid, " +
                      "CAST((((MAX(startkapital)*MAX(kapitalinvest)+SUM( summ))*100/(MAX(startkapital)*MAX(kapitalinvest)))-100) as BIGINT) as erg2 " +
                      "from Strategie o, testbedingung t, " +
                      "(SELECT SUM(guvtrade) as summ,ergebnisid,MAX(strategieid) as st FROM einzeltrade, ergebnis " +
                      "WHERE einkaufszeitpunkt >= '20100801 00:00:00' " +
                      " AND einkaufszeitpunkt <= current_date " +
                      " AND ergebnis.eid = einzeltrade.ergebnisid " +
                      " AND datenart = 0 " +
                      " GROUP BY ergebnisid) as tsum " +
                      "where showranking = 'true' " +
                      "AND t.tid = o.testbedingungid " +
                      "AND o.stid = tsum.st " +
                      "GROUP BY stid " +
                      "ORDER BY erg2 DESC").getResultList();
                      List<Ranking> actual=new ArrayList<Ranking>();
                      Ranking r;
                      for(Object[] rowList<Object[]>)temp){
                      r=new Ranking();
                      r.setStid(((BigInteger)row[0]).intValue());
                      r.setErg2(((BigInteger)row[1]).intValue());
                      actual.add(r);
                      }
                      return actual;
                      }

                      jetzt komme die ergebinse da an wo sie sollen.

                      Danke nochmal für die unterstüzung!

                      MfG
                      Tacco

                      Comment

                      Working...
                      X