Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Variable in View verwenden

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von strzata, 8 Mai 2017.

  1. strzata

    strzata Benutzer

    Hallo,
    ich suche nach einer Möglichkeit in einer View eine Variable zu verwenden. Auf das Wesentlche reduziert:
    SELECT CASE WHEN C01='Hamburg' THEN 'A' END FROM t800
    wobei die View (t800view) mit "Hamburg" als Variable aufgerufen werden soll.

    Hintergrund: Das SELECT ist sehr umfangreich und wird aus .Net heraus aufgerufen und das sehr oft, aber immer mit einer anderen Variablen. Ich will den Code nicht doppelt schreiben und es geht auch schneller, wenn ich die View mit "SELECT FROM t800view" starte. Hab gelesen, dass man eine Function in der View einbauen kann, hab es aber nicht hinbekommen. Hier mein SELECT in VB.Net (das soll mit der Variable regioKz in die View):

    dv = New DataView(iDBS.GetRecFromTable1("SELECT C2018,C2001,C2013,C2014,C2003,C2004,CONCAT(C2034,' ',C2035) AS C2035,C2040,C2041,CASE WHEN C2028<>'' THEN 'D' WHEN NOT(CURDATE() BETWEEN C2025 AND C2026 OR ISNULL(C2026)) THEN 'E' WHEN C2030='" & regioKz & "' THEN 'A' WHEN C2003=C2050 THEN 'B' ELSE 'C' END AS C2050 FROM t800 LEFT JOIN t801 ON t801.ID=t800.ID LEFT JOIN t804 ON t804.ID=t800.ID LEFT JOIN t805 ON t805.ID=t800.ID LEFT JOIN t807 ON t807.ID=t800.ID WHERE C2013 LIKE '%" & tbKasse.Text.Trim & "%' ORDER BY C2050,C2018,C2014"))

    Die erste Variable "regioKz" ist mein Problem. Die zweite Variable " tbKasse.Text" nicht, da ich sie im WHERE beim Aufruf der View unterbringen kann (SELECT * FROM t800view WHERE C2013 LIKE '%Barmer%')

    Es wäre wunderbar, wenn mir jemand die Lösung aufzeigen könnte. Danke.
     
  2. akretschmer

    akretschmer Datenbank-Guru

    durchnummerierte Tabellen und Spalten, was für ein Graus. Ansonsten: native SQL kennt keine Variablen. Du könntest eine Stored Proc schreiben, die Parameter übergeben bekommt und eine Tabelle als Resultat liefert. "Code nicht doppelt schreiben" ist kein Argument.
     
  3. strzata

    strzata Benutzer

    Danke, dass Du drüber geschaut hast. Kann man in einer View wirklich keine Function einbauen, die die Variable holt?
     
  4. akretschmer

    akretschmer Datenbank-Guru

    eine View ist lediglich ein Alias auf das SQL, auf dem die View basiert.
     
  5. drdimitri

    drdimitri Datenbank-Guru

    Doch, Bindvariablen. Und im allgemeinen kann man die nicht nur im WHERE sondern auch im SELECT Teil verwenden.
    In Java wären es PreparedStatements und ? als Platzhalter. Sprich
    Code:
    WHEN C2030=? THEN
    Wie es in C# oder welche .Net Sprache du auch verwendest, genau geht musst in der Doku nachsehen.
    Als View kannst das Statement dann nicht ablegen, aber das ist für den Fall auch egal. Einfach als Funktion im Code auslagern und den Wert der Bindvariable als Parameter übergeben, Recordset als Rückgabewert.
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Ja, wie Du schon sagst: "Wie es in C# oder welche .Net Sprache du auch verwendest, genau geht musst in der Doku nachsehen.". SQL ist das nicht.
     
  7. drdimitri

    drdimitri Datenbank-Guru

    Wieso ist das kein SQL?
     
  8. akretschmer

    akretschmer Datenbank-Guru

    weil reines SQL das nicht kann. Das macht der Treiber der jeweiligen Sprache, z.B. via prepared Statements. Der Fragesteller kann natürlich prepared Statements auch in SQL nutzen - spart dabei aber nicht Schreibaufwand. Und: prepared Statements können auch Nachteile haben: so weiß der Planner zur Planungszeit nicht, welche Werte die Parameter mal haben werden. Das führt gern zu, *ähm*, *hüstel*, konservativen Plänen.
     
  9. drdimitri

    drdimitri Datenbank-Guru

    Keine Ahnung, was du mit "reinem SQL" meinst, aber was ist ein Statement mit Bindvariablen?
    Das der Plan anders aussehen kann ist richtig, aber dafür gibt es z.B. in Oracle diverse Optimierungssrategien. Umgekehrt kannst eine Oracle Datenbank im OLTP Betrieb ohne Bindvariablen praktisch nicht benutzen.

    Binds im äußersten SELECT Block haben aber im allgemeinen keine Auswirkungen auf den Plan.
     
  10. akretschmer

    akretschmer Datenbank-Guru

    IIRC sind Bindvariable nicht Bestandteil der SQL-Spec. Das macht Ora oder T-SQL, ist aber keine Norm. Ist also hochgradig abhängig von der Implementation.
     
  11. drdimitri

    drdimitri Datenbank-Guru

    Wenn du meinst. Du bist der erste, der vor der Verwendung von Binds warnt weil sie nicht im Standard sind.
     
  12. akretschmer

    akretschmer Datenbank-Guru

    Huch? Hab ich so nicht gesagt. Vielleicht hilft es ja dem Fragesteller, warten wir also mal auf seine Antwort.
     
  13. strzata

    strzata Benutzer

    Oh je, da kann ich nicht mithalten bei eurer Diskussion. Ich bin nur Laie auf dem Gebiet. Die wichtigsten "einfachen" Dinge in MySql weiss ich, aber ihr geht ja richtig ans Eingemachte ;-)
    Dass es irgendwie gehen müsste habe ich im Internet gefunden:

    create function p1() returns INTEGER DETERMINISTIC NO SQL return@p1;
    create view h_parm as select * from mytable where id = p1();
    Aufruf:
    select s.*from(select@p1:=12 p) parm , h_parm s;

    Ich kann das nicht verstehen, geschweige denn umsetzen. In Vb.Net geht es wie in Java auch mit einem "?"
    Hab in meinem Code eine Function für eine SP wo man das sieht:

    Public Function KTStammFehler(ByVal InParameter As ArrayList) As ArrayList
    If Not OpenConnection1() Then Return New ArrayList

    Dim outArray As New ArrayList
    Dim dr As MySqlDataReader = Nothing
    Try

    Dim cmd As New MySqlCommand("gkv_kassen_pruefer", _conn1)
    cmd.CommandType = CommandType.StoredProcedure
    Dim p1 As New MySqlParameter("?ik", InParameter(0))
    Dim p2 As New MySqlParameter("?vknr", InParameter(1))
    Dim p3 As New MySqlParameter("?ktab", InParameter(2))
    Dim p4 As New MySqlParameter("?kv", InParameter(3))
    Dim p5 As New MySqlParameter("?quartal", InParameter(4))
    Dim p6 As New MySqlParameter("?plz", InParameter(5))
    cmd.Parameters.Add(p1)
    cmd.Parameters.Add(p2)
    cmd.Parameters.Add(p3)
    cmd.Parameters.Add(p4)
    cmd.Parameters.Add(p5)
    cmd.Parameters.Add(p6)

    dr = cmd.ExecuteReader
    dr.Read()
    For i As Integer = 0 To dr.FieldCount - 1
    outArray.Add(dr(i))
    Next
    Catch ex As Exception
    Throw New Exception(ex.Message & Environment.NewLine & "(KTStammFehler)" & Environment.NewLine & ex.Message)
    Finally
    If dr IsNot Nothing AndAlso Not dr.IsClosed Then dr.Close()
    If _conn1.State <> ConnectionState.Closed Then _conn1.Dispose()
    End Try
    Return outArray
    End Function

    Aber wie man die View und die Function bauen muss - da bin ich zu dumm dazu. Und eine SP möchte ich erstmal nicht. Könnt ihr beiden mir noch ein Stückchen weiter helfen?

     
  14. akretschmer

    akretschmer Datenbank-Guru

    Ich bin raus. In PG würde ich, wie schon gesagt, eine SP schreiben, die eine Tabelle zurückliefert.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden