none
Werte aus Textboxen multiplizieren und in SQL Server 2012 speichern RRS feed

  • Frage

  • Hallo,

    ich bin noch ziemlich neu in Visual Studio 2012 uns komme momentan mit einer sicher recht einfachen Sache nicht weiter.

    Ich habe auf einer Windows Form Seite  unter anderem 3 TextBoxen, deren Werte ich in SQL Server 2012 speichern möchte.

    TextBox 1    Wert =  2.25     Definition SQL-Server Spalte  Typ  decimal(18,2)

    TextBox 2     Wert=15.50     Definition SQL-Server Spalte  Typ  money

    TextBox 3   = Soll den Wert der Multiplikation aus TextBox 1 * TextBox 2 bekommen

    und dann  und in SQL Server Spalte  Typ money eingetragen werden.

    Alle versuchen scheiterten bisher mit den unterschiedlichsten Fehlermeldungen.

    Die Insert-Anweisung enthält mehr Spalte als Select

    Fehler bei Konvertierung von varchar in numeric etc.

    Als Anhang noch der Code-Schnipsel

    Dim sqlConnection As New System.Data.SqlClient.SqlConnection("integrated security=SSPI;data source=XXXX;persist security info=False;initial catalog=CSH")
            Dim cmd As New System.Data.SqlClient.SqlCommand
    
            Dim a As Integer
            Dim b As Integer
            Dim c As Date
            Dim d As String
            Dim m As String
            Dim bz As String
            Dim p As String
            Dim g As Double
            Dim erh As Integer
            Dim bem As String
            Dim mat As Integer
            Dim ges As String
    
            a = CInt(laufknr.Text)
            b = CInt(laufpid.Text)
            c = laufdatum.Text
            d = laufaufg.Text
            m = laufanz.Text
            bz = laufbze.Text
            p = laufstdsatz.Text
    
    
            g = m * p
            ges = g.ToString("N1")
    
    
            If chkerhalt.Text = "" Then
                chkerhalt.Text = 0
            End If
            erh = chkerhalt.Text
    
    
            If chkmaterial.Text = "" Then
                chkmaterial.Text = 0
            End If
            mat = chkmaterial.Text
    
            bem = laufbem.Text
    
            Stop
    
    
            Dim cn As New SqlConnection
            cn.ConnectionString = "integrated security=SSPI;data source=GHW8PX64;persist security info=False;initial catalog=CSH"
            cmd.Connection = cn
            cn.Open()
            cmd.CommandText = "Insert into  tbl_leistung(pid, kid, a_datum, a1, menge, bze ,h_satz, gesamt, erhalten, bem, material)  Values ( " & b & " ," & a & " , '" & c & "', '" & d & "', '" & m & "', '" & bz & "' , '" & p & "', '" & g & "', " & erh & ", '" & bem & "', " & mat & " )"
            cmd.ExecuteNonQuery()
            MsgBox("Daten wurden erfolgreich eingetragen!", vbOKOnly, "Termin einfügen")
            cn.Close()
    
    
            Dim bs1 As New BindingSource
            Dim dt1 As New DataTable
            Dim da1 As New SqlClient.SqlDataAdapter
            Dim ds As New DataSet
    
            Dim str1 As String = "select * from tbl_leistung where pid = " & b & ""
    
            da1.SelectCommand = New SqlCommand(str1, cn)
            da1.Fill(ds)
            cn.Close()
            DataGridView1.DataSource = ds.Tables(0)
    
            DataGridView1.Refresh()

    Die Variablen, welche die benötigten Werte enthalten sind m, p und g

    Sonntag, 31. März 2013 17:30

Antworten

  • soweit ich weiß liegt das am Format, in dem die DB alles haben möchte. .NET liefert alle möglichen Daten immer im Schema des aktuellen Raumes, also 12,3 für Kommazahlen. Die DB will aber das englische Format haben: 12.3

    Ich denke das einfachste wäre ein double daraus zu erstellen und dieses im englischen Format wieder in einen String zu wandeln:

    Double.Parse(TextBox1.Text).ToString(New CultureInfo("en-us"))


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.

    • Als Antwort markiert Gerd_Haseloff Freitag, 5. April 2013 09:58
    Sonntag, 31. März 2013 20:15
    Moderator
  • Hallo Gerd,

    wie Koopakiller schon richtig schrieb, liegt es am vom SQL Server erwarteten Format der Zahlen und das Du hier dynamisch zusammengestellte SQL Statements verwendest, und das noch auf eine sehr "ungünstige" weise.

    Z.B. das zuletzt erwähnte Feld "h_satz", den Wert dafür baust Du mit

    , '" & p & "',

    in das Statement, also mit zusätzlichen Hochkommas, es wird somit zunächst als String Value übergeben und wenn es eine Dezimalzahl ist, sieht es im SQL Statement so aus

    , '12,3', 

    Im EN-US Format, das der SQL Server erwartet, ist das Komma ein Tausendertrenner und wird schlichtweg ignoriert; Ergebnis ist dadurch der Wert 123 und nicht 12,3.
    Wenn Du die Hochkomma's weg lässt, was Du vermutlich schon versucht hast, bekommst Du die im ersten Post erwähnte Fehlermeldung "Die Insert-Anweisung enthält mehr Spalte als Select"; denn dann wird das Komma nicht als Tausender-, sondern als Wertetrennzeichen betrachtet.

    Entweder formatierst Du die Werte wie von Koopakiller vorgeschlagen im EN-US Format, oder noch besser, Du arbeitest Grundsätzlich nur mit SqlParameter, denn das Formatierungsproblem wird an anderen Stellen auch noch auf Dich zukommen, wie bei Datumswerten. Zudem bringt es auch leichte Performanzvorteile.
    Siehe z.B. Konfigurieren von Parametern und Parameterdatentypen


    Olaf Helper

    Blog Xing


    Montag, 1. April 2013 17:36
  • Halo Gerd,

    ein Beispiel für die Verwendung von SqlParametern (ist VB.NET, auch wenn ich dort im C# Forum gepostet hatte^^) findest Du hier:

      http://social.msdn.microsoft.com/Forums/de-DE/visualcsharpde/thread/7896fb46-5792-476f-aa42-47c241c08b30#619febd6-c063-4315-b18c-c21abea7c4ae


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Donnerstag, 4. April 2013 16:44
    Moderator
  • Hallo Gerd,

    das DataGridView zeigt die Daten so an, wie Du es definiert hast (oder je nach Defaulteinstellung für den entsprechenden Datentyp). Siehe dazu:

      http://msdn.microsoft.com/de-de/library/ms171598.aspx

    Hast Du die einzelnen Spalten manuell im Gridview festgelegt oder wird das automatisch aufgebaut?

    Das SQL Statement hat damit nichts zu tun.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community



    Donnerstag, 4. April 2013 19:58
    Moderator
  • Die Spaltendarstellung erfolgt derzeit automatisch.

    Hallo Gerd,

    dann wäre das etwas, was Du umstellen solltest. Die automatische Verarbeitung hat halt eben ihre Tücken^^ Bei manuellem Aufbau hast Du eine erheblich bessere Kontrolle über die Ausgabe.

    Ggfs. geht es auch mit einem DefaultCellStyle, wobei ich nicht denke, dass das mit AutoGenerateColumns zusammenspielt.

      http://msdn.microsoft.com/de-de/library/k4sab6f9.aspx

    Alternativ könntest Du den Wert auch als String laden. Das ist allerdings nicht wirklich sinnvoll, da dann auch sortierung, Filterung, ... nicht mehr so funktionieren, wie man es von einer Zahl erwartet.

    BTW: Es wäre nun sinnvoll, diesen Thread abzuschließen und die weiteren Fragen in einem neuen Thread zu stellen. Ansonsten geht hier doch die Übersicht etwas verloren.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Donnerstag, 4. April 2013 21:43
    Moderator

Alle Antworten

  • Hallo,

    Ich bin nicht der Profi, was Datenbankprogrammierung angeht, aber eine Einfache Variante zu einfügen und Auslesen von Datensätzen findest du hier: http://openbook.galileocomputing.de/einstieg_vb_2008/visual_basic_kap_11_008.htm

    Anhand dieses Codes habe ich diese kleine Anwendung zusammen gebastelt: http://sdrv.ms/Zvj710

    Grundsätzlich scheinst du es schon richtig gemacht zu haben, nur dein ConnectionString verwirrt mich etwas.

    Den CommandText so zusammen zu setzen funktioniert zwar kann jedoch auch eine große Sicherheitslücke werden. Siehe SQL Injection. Eine mögliche Variante zur Vorbeugung:
    ttp://stackoverflow.com/questions/4018174/preventing-sql-injection-in-asp-net-vb-net


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.

    Sonntag, 31. März 2013 18:00
    Moderator
  • Hallo,

    danke für die schnelle Antwort,

    nur bringt sie mich nicht wirklich weiter. Wenn ich in die TextBox 15,5 eingebe trägt er in die

    Datenbank 155 ein. Dieses Phänomen hatte ich auch schon, weiß nur nicht, warum er dies macht.

    Und die Multiplikation von 2.5 * 18,00  lieferte dann  4500. Hätte eigentlich gern die wirklichen Werte.

    Gruß Gerd

    Sonntag, 31. März 2013 19:22
  • soweit ich weiß liegt das am Format, in dem die DB alles haben möchte. .NET liefert alle möglichen Daten immer im Schema des aktuellen Raumes, also 12,3 für Kommazahlen. Die DB will aber das englische Format haben: 12.3

    Ich denke das einfachste wäre ein double daraus zu erstellen und dieses im englischen Format wieder in einen String zu wandeln:

    Double.Parse(TextBox1.Text).ToString(New CultureInfo("en-us"))


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.

    • Als Antwort markiert Gerd_Haseloff Freitag, 5. April 2013 09:58
    Sonntag, 31. März 2013 20:15
    Moderator
  • Hallo,

    habe ich gemacht.

    Resultat siehe:

    Ergebnis Einfügen in DB aus Textboxen

    Sonntag, 31. März 2013 20:57
  • Ich habe für mein Beipiel eine lokale SDF-Datei genutzt, bei der ging es so. Was für einen Typ hast du denn gewählt? Ich habe einmal money und einmal float probiert, bei beiden klappt es problemlos.

    Mir gehen jetzt auch die Ideen aus. Vielleicht kannst du mal die Projektmappe auf SkyDrive o.ä. hoch laden, dann kann ich mal drüber sehen. Alternativ wird den Thread bestimmt demnächst jemand finden, der sich besser mit DB's auskennt, aber ich weiß nicht wie lange das noch dauert.


    <Code:13/> - Koopakiller [kuːpakɪllɐ]
    Webseite | Code Beispiele | Facebook | Snippets
    Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.

    Sonntag, 31. März 2013 21:29
    Moderator
  • Wie gesagt,

    ich verwende einen SQL Server 2012 Developer,

    das Feld

    -Menge-

    besitzt den Typ Decimal(18,2)

    das Fels h_satz

    den Typ Money 

    und gesamt den Typ Money

    und soll eigentlich den Wert von

    Menge * h_satz aufnehmen

    Projektmappe hier:

    https://skydrive.live.com/#cid=88E265DAF44597C4&id=88E265DAF44597C4%21104

    Sonntag, 31. März 2013 22:05
  • Hallo Gerd,

    wie Koopakiller schon richtig schrieb, liegt es am vom SQL Server erwarteten Format der Zahlen und das Du hier dynamisch zusammengestellte SQL Statements verwendest, und das noch auf eine sehr "ungünstige" weise.

    Z.B. das zuletzt erwähnte Feld "h_satz", den Wert dafür baust Du mit

    , '" & p & "',

    in das Statement, also mit zusätzlichen Hochkommas, es wird somit zunächst als String Value übergeben und wenn es eine Dezimalzahl ist, sieht es im SQL Statement so aus

    , '12,3', 

    Im EN-US Format, das der SQL Server erwartet, ist das Komma ein Tausendertrenner und wird schlichtweg ignoriert; Ergebnis ist dadurch der Wert 123 und nicht 12,3.
    Wenn Du die Hochkomma's weg lässt, was Du vermutlich schon versucht hast, bekommst Du die im ersten Post erwähnte Fehlermeldung "Die Insert-Anweisung enthält mehr Spalte als Select"; denn dann wird das Komma nicht als Tausender-, sondern als Wertetrennzeichen betrachtet.

    Entweder formatierst Du die Werte wie von Koopakiller vorgeschlagen im EN-US Format, oder noch besser, Du arbeitest Grundsätzlich nur mit SqlParameter, denn das Formatierungsproblem wird an anderen Stellen auch noch auf Dich zukommen, wie bei Datumswerten. Zudem bringt es auch leichte Performanzvorteile.
    Siehe z.B. Konfigurieren von Parametern und Parameterdatentypen


    Olaf Helper

    Blog Xing


    Montag, 1. April 2013 17:36
  • Hallo Gerd,

    Wenn Dir die Antworten geholfen haben dann bitte markiere diese als Antwort.

    Gruss,

    Ionut

    Donnerstag, 4. April 2013 14:10
    Moderator
  • Hallo Olaf,

    danke für die Antwort.

    Sicher hast du recht und Erklärung ist nachvollziehbar.

    Ich bin und war schon beim googeln  nach einem für ein mich brauchbares Beispiel.

    Bin aber noch nicht wirklich fündig geworden.

    Über eine kleine Hilfestellung für meinen konkreten Fall wäre ich sehr froh.

    Gerd Haseloff 

    Donnerstag, 4. April 2013 16:31
  • Halo Gerd,

    ein Beispiel für die Verwendung von SqlParametern (ist VB.NET, auch wenn ich dort im C# Forum gepostet hatte^^) findest Du hier:

      http://social.msdn.microsoft.com/Forums/de-DE/visualcsharpde/thread/7896fb46-5792-476f-aa42-47c241c08b30#619febd6-c063-4315-b18c-c21abea7c4ae


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Donnerstag, 4. April 2013 16:44
    Moderator
  • Hallo,

    danke für die vielen Anregungen.

    Ich habe es anscheinend gerafft und es funktioniert, wie gewünscht.

    Doch taucht gleich eine neue Ungereimtheit auf. Die Daten werden korrekt gespeichert und  sollen anschließend in einem DataGridView angezeigt werden.

    Die Abfrage im SQL-Management-Studio getestet liefert eigentlich die Werte, welche ich im DataGridView zu sehen wünsche.

    Nur das DataGridView zeigt 4 Nachkomma-Stellen statt 2.

    Wie kann man dies hinbekommen?

    Gruß Gerd

    Hier noch kurz der Text der Abfrage:

    select lid,pid,kid,a_datum,a1, Round(menge,2) as menge, bze, Round(h_satz,2) as h_satz, Round(gesamt,2) as gesamt, erhalten, bem, material from tbl_leistung"

    .Value & ""

    Donnerstag, 4. April 2013 19:51
  • Hallo Gerd,

    das DataGridView zeigt die Daten so an, wie Du es definiert hast (oder je nach Defaulteinstellung für den entsprechenden Datentyp). Siehe dazu:

      http://msdn.microsoft.com/de-de/library/ms171598.aspx

    Hast Du die einzelnen Spalten manuell im Gridview festgelegt oder wird das automatisch aufgebaut?

    Das SQL Statement hat damit nichts zu tun.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community



    Donnerstag, 4. April 2013 19:58
    Moderator
  • Die Spaltendarstellung erfolgt derzeit automatisch.

    Gruß  Gerd

    Donnerstag, 4. April 2013 21:04
  • Die Spaltendarstellung erfolgt derzeit automatisch.

    Hallo Gerd,

    dann wäre das etwas, was Du umstellen solltest. Die automatische Verarbeitung hat halt eben ihre Tücken^^ Bei manuellem Aufbau hast Du eine erheblich bessere Kontrolle über die Ausgabe.

    Ggfs. geht es auch mit einem DefaultCellStyle, wobei ich nicht denke, dass das mit AutoGenerateColumns zusammenspielt.

      http://msdn.microsoft.com/de-de/library/k4sab6f9.aspx

    Alternativ könntest Du den Wert auch als String laden. Das ist allerdings nicht wirklich sinnvoll, da dann auch sortierung, Filterung, ... nicht mehr so funktionieren, wie man es von einer Zahl erwartet.

    BTW: Es wäre nun sinnvoll, diesen Thread abzuschließen und die weiteren Fragen in einem neuen Thread zu stellen. Ansonsten geht hier doch die Übersicht etwas verloren.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Donnerstag, 4. April 2013 21:43
    Moderator