Autor Beitrag
DennisXX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Sa 13.08.11 15:40 
Hallo !

Wie kann ich einem SQL Insert Statement einen Wert im C Sharp Code übergeben, der in einem Formular Textfeld eingegeben wurde?

Ich bekomme das bisher leider nur mit festen Werte hin. Kann mir jemand weiterhelfen?

Grüße
Dennis


Moderiert von user profile iconTh69: Kleine Rechtschreibfehler u.a. im Titel bereinigt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19322
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 13.08.11 16:09 
Eigentlich kannst du die einfach mit dem restlichen String verketten. :gruebel:

Wie hast du es denn jetzt?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 13.08.11 17:24 
Hallo zusammen,

bei SQL sollte man jedoch besser mit Parametern arbeiten, s. Artikelserie: Parameter von SQL Befehlen von JüTho
DennisXX Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Sa 13.08.11 19:35 
Hallo nochmal !

Danke für den Link !

ich habe mir dort mal das folgende Codebsp. herausgepickt und dazu mal eine Frage. Was genau wird in der Zeile "sb.AppendLine("OUTPUT INSERTED.ID");" bewirkt? Die restliche Codezeile sind für mich halbwegs verständlich:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
public int AddEmployee(string lastName, string firstName, double sallary, DateTime birthday)
{
  using (SqlConnection connection = new SqlConnection(ConnectionSting))
  {
    connection.Open();

    StringBuilder sb = new StringBuilder();
    sb.AppendLine("INSERT INTO [Employees] ([LastName], [FirstName], [Sallary], [Birthday])");
    sb.AppendLine("OUTPUT INSERTED.ID");
    sb.AppendLine("VALUES (@LastName, @FirstName, @Sallary, @Birthday)");

    using (SqlCommand cmd = new SqlCommand(sb.ToString(), connection))
    {
      cmd.Parameters.AddWithValue("LastName", lastName);
      cmd.Parameters.AddWithValue("FirstName", firstName ?? Convert.DBNull);
      cmd.Parameters.AddWithValue("Sallary", sallary);
      cmd.Parameters.AddWithValue("Birthday", birthday);

      return cmd.ExecuteNonQuery();
    }
  }
}


Hat das eigentlich irgendeinen speziellen Grund, weshlab hier mit der Klasse StringBuiler gearbeitet wird und nciht mit der Klasse String?

Danke für die Hilfe !

Grüße
Dennis
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 13.08.11 19:59 
Hallo Dennis,

das "OUTPUT INSERTED.ID" gibt den Rückgabewert des SQL-Befehls an (in diesem Fall die mittels einer "Autoincrement"-Spalte erzeugte Id). Ich weiß aber nicht, ob dies alle Datenbanksysteme unterstützen.

Und den StringBuilder benutzt man, wie der Name schon sagt, zum Zusammensetzen von längeren Strings. Beim "+" von zwei Strings wird intern immer eine neuer String erzeugt und die Strings immer kopiert, während der StringBuilder im voraus Speicher reserviert, so daß nur selten intern der String kopiert werden muß (ist also eine Performanceverbesserung).
Und mit der StringBuilder.ToString()-Methode erhält man dann den zusammengesetzten String.
DennisXX Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: So 14.08.11 09:13 
Hi Folks !

Ok die Argumentation mit der Klasse StringBuilder macht wirklich Sinn, besonders dann, wenn man längere Strings zusammenbaut denke ich mir mal.

Also das mit der Codezeile "sb.AppendLine("OUTPUT INSERTED.ID");" ist mir immernoch ncht ganz klar.

Ok, sie gibt einen autoinkrement Value zurück, aber wofür brauche ich diesen denn? Eigentlich muss doch das DBMS von sich aus erkennen, wann wo in der Datenbank der nächste einzutragene Tupel stattfinden soll oder sehe ich das falsch? Macht diese Spalte nciht mehr Sinn beim Auslesen der Daten aus einer Datenbank?

Greetz
Dennis
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 14.08.11 09:42 
Hallo Dennis,

Sinn macht die Rückgabe der Id, wenn man mehrere Tabelleneinträge einfügt, z.B. erst einen Employer (Angestellten) und dann z.B. dessen Lohnauszahlung in einer zweiten Tabelle, wo man dann die Id als ForeignKey benötigt (ansonsten müßte man ja nochmals diesen Datensatz lesen, um an die Id ranzukommen - außerdem müssten dann ja z.B. Name und Vorname eindeutig sein).

Generell dient ja ein "Autoincrement"-Wert als PrimaryKey, d.h. um sicherzustellen, daß jeder Datensatz eindeutig referenziert wird (ansonsten müßte man ja selber eine Id vom Programm aus vergeben - und das gibt große Probleme mit MultiUser-Anwendungen!).

s.a. www.sqlteam.com/arti...on-multi-row-inserts
sowie OUTPUT-Klausel (Transact-SQL)
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: So 14.08.11 19:28 
Hallo,
naja, über die Verwendung des StringBuilder's kann man bei diesem Code streiten. Denn der String steht ja fest und muss nicht erst zusammengebaut werden.
Genauso gut kann ich es auch so schreiben:
ausblenden C#-Quelltext
1:
2:
3:
4:
string stmt =
  @"INSERT INTO [Employees] ([LastName], [FirstName], [Sallary], [Birthday])
    OUTPUT INSERTED.ID
    VALUES (@LastName, @FirstName, @Sallary, @Birthday)"
;
Finde ich persönlich übersichtlicher. Und erzeugt auch nur einen String.
LG,
DennisXX Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 133



BeitragVerfasst: Mo 15.08.11 14:54 
Hallo nochmal !!

Eine Frage nochmal zu den beiden Codezeilen:

ausblenden Quelltext
1:
2:
string strValueTextfield = txtValues.Text; 
String strCurrentSQLStatement = @"INSERT INTO [tbl_SQL_Statements] ([SQL_Statement]) VALUES (@strValueTextfield)";


Der Wert wird korrekt aus dem Textfeld des Forulars ausgelesen! Aber leider wird der Wert im SQL befhel nicht korrekt interpretiert. Verwende ich den evtl. nicht korrekt, fehlt da noch etwas?

Grüße
Dennis
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Di 16.08.11 19:07 
user profile iconDennisXX hat folgendes geschrieben Zum zitierten Posting springen:
Verwende ich den evtl. nicht korrekt, fehlt da noch etwas?

Ja, da fehlt einfach mal das Adden des Parameters zu dem Command. Wie setzt Du denn den Command ab?
Es müsste doch irgendwie so aussehen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
String strCurrentSQLStatement = @"INSERT INTO [tbl_SQL_Statements] ([SQL_Statement]) VALUES (@strValueTextfield)";
using (SqlCommand cmd = new SqlCommand(sb.ToString(), connection))
{
  cmd.Parameters.AddWithValue("@strValueTextfield", txtValues.Text);
  cmd.ExecuteNonQuery();
}