2016-07-23 6 views
0

Dies ist ein wenig schwer zu erklären, also bitte bitte mit mir.
Ich arbeite mit einer SQL-Tabelle über die Konsole C#.

Ich bin an dem Punkt, wo der Endbenutzer in der Lage sein muss, den Primärschlüssel Wert ändern zB Klassennamen

Wenn der Benutzer versucht, einen Primärschlüssel Wert, der bereits existiert, das erste Mal sql/c#catches it und gibt eine Exception und das Programm wird als normal Schleife es zurück zu dem Teil, wo der Benutzer den doppelten Primärschlüssel Wert eingegeben.

Wenn Sie jedoch versuchen, Daten erneut hinzuzufügen und einen Wert hinzuzufügen, der bereits als Primärschlüsselwert vorhanden ist, wird das zweite Mal nicht catch.

Hier ist eine Timeline.

C# - SQL findet keinen doppelten Wert im Primärschlüssel

  1. Geben Sie das neue Gruppenmenü
  2. Details zum Update auf einem Gruppe nennen, aber dass Gruppen Namen schon existiert, so teilt es den Anwender noch einmal zu versuchen und Schleifen sie zurück zu der Teil bitten, eine neue Gruppe hinzufügen
  3. Endbenutzer fügt die richtigen Details und arbeitet weiter mit dem Programm
  4. Später wurde der Endbenutzer versucht, die Details eines gro zu aktualisieren up und fügen Sie einen Namen hinzu, der bereits existiert, aber dieses Mal erhebt es keine Exception, aber arbeitet weiter, wenn es nicht sollte.



Hier ist der Code hinter der Schleife, die oben erwähnt wurden.

UPDATE: Hinzufügen des gesamten Moduls, um einige der folgenden Kommentare zu beantworten.

static void editTable() 
    { 
     int j = 0; 
    top: 
     SQLCONN.Open(); 
     var TIME = DateTime.Now; 
     SqlCommand cmd0 = new SqlCommand("SELECT * FROM dbo."+selectedDayTableToEdit+"Table", SQLCONN); 
     SqlDataReader reader = cmd0.ExecuteReader(); 
     while (reader.Read()) 
     { 
      int n = 1; 
      int p = 1; 
      Console.WriteLine("------------------------------------------------------------"); 
      Console.WriteLine(" [" + reader.GetValue(n).ToString() + " TIMES]  [TEACHER/CLASSROOM]  {0} " + TIME.ToString("HH:mm:ss"), selectedDayTitle); 
      Console.WriteLine("------------------------------------------------------------"); 

      for (int i = 2; i < reader.FieldCount; i++) 
      { 
       Console.WriteLine(p +" - " + reader.GetName(i) + "  " + reader.GetValue(i)); 
       p++; 
      } 
     } 

     SQLCONN.Close(); 
     repeat: 
     Console.WriteLine(); 
     Console.WriteLine("Which group would you like to edit?"); 
     string Group = Console.ReadLine().ToUpper(); 
     Console.WriteLine("Enter {0}'s new group name if any", Group); 
     string newGroup = Console.ReadLine().ToUpper(); 
     if (string.IsNullOrEmpty(newGroup)) 
     { 
      check = true; 
      newGroup = string.Format("{0}", Group); 
     } 
     else 
     { 
      check = false; 
     } 
     SQLCONN.Open(); 
     //update Group Name (SAT) 
     try 
     { 
       if(check == false) 
      { 
     using (SqlCommand cmd = new SqlCommand("UPDATE " + selectedDayTableToEdit + "Table SET [email protected] where [email protected]" + Group, SQLCONN))//2nd @ what its looking for. 
       { 
        cmd.Parameters.AddWithValue("@CLASSNAME", newGroup); 
        cmd.Parameters.AddWithValue("@" + Group, Group); 
        cmd.ExecuteNonQuery(); 
        Console.WriteLine("Database Updated..."); 
       } 
      } 
     } 
     catch (Exception) 
     { 
      Console.WriteLine(); 
      Console.WriteLine("That group already exists"); 
      Console.ReadKey(); 
      SQLCONN.Close(); 
      goto repeat; 
     } 
     SQLCONN.Close(); 
     Console.WriteLine(); 
     Console.WriteLine("Which time would you like to edit for group {0}?", newGroup); 
     string RESULT = Console.ReadLine(); 
     string ClassTime = ""; 
     switch (RESULT) 
     { 
      case "1": 
       ClassTime = "09:00-09:40"; 
       break; 
      case "2": 
       ClassTime = "10:10-10:50"; 
       break; 
      case "3": 
       ClassTime = "11:00-11:40"; 
       break; 
      case "4": 
       ClassTime = "11:50-12:30"; 
       break; 
      case "5": 
       ClassTime = "12:40-13:20"; 
       break; 
      case "6": 
       ClassTime = "13:30-14:10"; 
       break; 
      case "7": 
       ClassTime = "14:20-15:00"; 
       break; 
      case "8": 
       ClassTime = "15:10-15:50"; 
       break; 
      case "9": 
       ClassTime = "16:00-16:40"; 
       break; 
      case "10": 
       ClassTime = "16:50-17:30"; 
       break; 
      case "11": 
       ClassTime = "17:40-18:20"; 
       break; 
      case "12": 
       ClassTime = "18:30-19:10"; 
       break; 
      case "13": 
       ClassTime = "19:20-20:00"; 
       break; 
      default: 
       Console.WriteLine("A time was not selected..."); 
       Console.WriteLine("Returning to main menu"); 
       Console.ReadKey(); 
       menu(); 
       break; 
     } 
     //Console.WriteLine("Enter the current teacher and classroom for {0}", newGroup); // DONT NEED THIS ANYMORE?? 
     //string teacherandclassroom = Console.ReadLine().ToUpper(); 
     Console.WriteLine(string.Format("Enter the new teacher and classroom number for group {0} at {1} ", newGroup, ClassTime)); 
     string newTeacherClassRoom = Console.ReadLine().ToUpper(); 
     SQLCONN.Open(); 
     try 
     { 
      using (SqlCommand cmd1 = new SqlCommand("UPDATE "+selectedDayTableToEdit+"Table SET [" + ClassTime + "] = @newValue WHERE [CLASSNAME] [email protected]" + newGroup, SQLCONN)) //or WHERE newGroup? 
      { 
       cmd1.Parameters.AddWithValue("@newValue", newTeacherClassRoom); //@ can be whatever as long as its the same as the queries 
       cmd1.Parameters.AddWithValue("@" + newGroup, newGroup); 
       cmd1.ExecuteNonQuery(); 
       Console.WriteLine("Database Updated..."); 
      } 
      SQLCONN.Close(); 
      Console.ReadKey(); 
      menu(); 
     } 
     catch (SqlException) 
     { 
      SQLCONN.Close(); 
      Console.Clear(); 
      Console.WriteLine("ERROR UPDATING RECORDS...."); 
      Console.ReadKey(); 
      Console.Clear(); 

      if (j == 1) 
      { 
       menu(); 

      } 
      else 
      { 
       j++; 
       goto top; 
      } 
     } 
    } 


UPDATE
Ich habe eine ID Primärschlüssel für eine ganze Zahl und entfernt die GC
Vielen Dank allen für die Kommentare und mir Vorschläge, was ich sollte in der Tat viel tun, geschätzt, da hinzugefügt!
Das Problem war mit der check Boolean zu tun, danke an alle, die darauf hingewiesen.

+1

Sie sollten versuchen, mit einem Primärschlüssel zu vermeiden Wert, der Ihnen wichtig genug ist, um ihn in zukünftigen Datenbankdesigns zu ändern. Es erzeugt alle Arten von Kopfschmerzen, wenn Updates durchgeführt werden. –

+0

Ich behalte das im Hinterkopf @ LasseV.Karlsen :) Für diese Datenbank wird der Benutzer nicht ändern eine primäre Schlüsselwerte auf einer täglichen Basis, das ist nur für den Fall, dass sie es tun. – Werdna

+1

@Werdna. . . Sie sollten eine Identitätsspalte als Primärschlüssel mit dem Namen als Attribut haben. Sie können eine eindeutige Einschränkung für den Namen erstellen, um sicherzustellen, dass keine Duplizierung erfolgt. –

Antwort

0
check = true; //weird because its working if false??? 

Sie wissen, was seltsam ist, ist man es nicht mit anderen falschen

if (string.IsNullOrEmpty(newGroup)) 
{ 
    newGroup = string.Format("{0}", Group); // what is the purpose of this? 
    check = true; //weird because its working if false??? 
} 
else 
    check = false; 

einverstanden eingestellt Antwort auf

cmd.Parameters.AddWithValue("@GroupName", Group); 

und tun dies nicht

GC.Collect(); 
GC.WaitForPendingFinalizers(); 

und Sie scheitern Gruppe zu prüfen, für null oder leer

warum auch öffnet die Verbindung, wenn

if (check == false) 

ein wenig sauberen

repeat: 
    Console.WriteLine(); 
    Console.WriteLine("Which group would you like to edit? Blank to exit."); 
    string Group = Console.ReadLine().ToUpper(); 
    if(string.IsNullOrEmpty(Group)) 
     exit; // this may be return - I forget 
    Console.WriteLine("Enter {0}'s new group name if any", Group); 
    string newGroup = Console.ReadLine().ToUpper(); 
    if(string.IsNullOrEmpty(newGroup)) 
     goto repeat; 
    SQLCONN.Open(); 
    //update Group Name (SAT) 
    try 
    { 
     using (SqlCommand cmd = 
     new SqlCommand("UPDATE " + selectedDayTableToEdit + "Table SET [email protected] where [email protected]", SQLCONN)) 
     { 
      cmd.Parameters.AddWithValue("@NewGroup", newGroup); 
      cmd.Parameters.AddWithValue("@Saat", Group); 
      cmd.ExecuteNonQuery(); 
      Console.WriteLine(); 
      Console.WriteLine("Database Updated..."); 
     } 
    } 
    catch (Exception) 
    { 
     Console.WriteLine(); 
     Console.WriteLine("That group already exists"); 
    } 
    finally 
    { 
     SQLCONN.Close(); 
    } 
    goto repeat; 
+0

Cheers Paparazzi für Ihre Hilfe, änderte ich am Ende der Tabelle, so dass der Primärschlüssel nicht geändert werden musste und endete auch die Prüfung Teil, ich habe die "string.IsNullOrEmptry (newGroup)) "das du vorgeschlagen hast, sehr nett in der Tat :) – Werdna

+0

Und diese Antwort hat immer noch keinen Haken. – Paparazzi

+0

Hey @Paparazzi, war ich nicht zu benutzen, wenn ich es als richtig machen sollte, da ich jeden Input verwendete ?? – Werdna

1

keine Antwort, aber einige zu groß Noten für Bemerkungen:

 SQLCONN.Open(); 

Diese Linie mich betrifft. Sie sollten jedes Mal eine neue Verbindung mit einem using Block erstellen, um sicherzustellen, dass sie ordnungsgemäß zerstört wird. Das Teilen eines Verbindungsobjekts ist sehr schwierig, auch wenn es kein Multi-Threading ist.

Hinweis: Technisch gesehen schließt das Schließen einer Verbindung es nicht wirklich. Es wird nur zur späteren Wiederverwendung in einen Verbindungspool zurückgegeben. Aber darüber musst du nicht nachdenken.


GC.Collect(); 
    GC.WaitForPendingFinalizers(); 

Verwirren Sie nicht um mit dem Garbage Collector. Dies ist eine sehr fortgeschrittene Technik, die nur für einige Testformen und unglaublich leistungsstarke Anwendungen geeignet ist. Und selbst dann ist es schwer zu lernen, wie man es richtig macht.


new SqlCommand("UPDATE " + selectedDayTableToEdit + "Table SET [email protected] where [email protected]" + Group, SQLCONN)) 
      { 
       cmd.Parameters.AddWithValue("@Saat", newGroup); 
       cmd.Parameters.AddWithValue("@" + Group, Group); 
       cmd.ExecuteNonQuery(); 
       Console.WriteLine("Database Updated..."); 
      } 

Das ist wirklich ist, wirklich schlecht. Sie erstellen eine SQL-Anweisung mit Arbitraty-Text. Wenn jemand das Gleiche von der Gruppe sagt "tom; Delete FROM MyTable", dann werden Sie alles in der Tabelle löschen.

Darüber hinaus wird jedes Mal, wenn Sie den Variablennamen ändern, ein neuer Ausführungsplan erstellt.

new SqlCommand("UPDATE " + selectedDayTableToEdit + "Table SET [email protected] where [email protected]", SQLCONN)) 
      { 
       cmd.Parameters.AddWithValue("@Saat", newGroup); 
       cmd.Parameters.AddWithValue("@GroupName", Group); 
       cmd.ExecuteNonQuery(); 
       Console.WriteLine("Database Updated..."); 
      } 

Ich mag es nicht selectedDayTableToEdit + "Table auch nicht, aber das ist unvermeidlich, wenn der Tabellenname ändern kann. Dennoch wäre es viel besser, eine große Tabelle zu erstellen, so dass Sie schreiben können:

new SqlCommand("UPDATE DatTable SET [email protected] where [email protected] AND [email protected]", SQLCONN)) 
+0

Vielen Dank @Jonathan Allen für Ihren Einblick, was ich tun würde, ich hatte nicht zu viel mit Tabellen aus C# -Konsole vorher zu tun, so dass es immer noch ziemlich neu, danke für Ihre Antwort, ich bin mir sicher Um es wieder und wieder zu gehen :) – Werdna

Verwandte Themen