none
MS SQL Server Tabelle in andere Tabelle schreiben RRS feed

  • Frage

  • Hallo,

    Ich habe 2 Tabellen, die dbo.Angebot und die dbo.Angebotdetails die über die AngebotID verknüpft sind. Über einen Button sollen diese Daten in die Tabellen dbo.Auftrag und dboAuftragdetails ebenfalls über AuftragID verknüpft geschrieben werden.

    Wie kann ich das am besten lösen?


                SqlConnection con = new SqlConnection(@"Data Source =.\SQLEXPRESS; Initial Catalog = Test; Integrated Security = True");
                con.Open();
                SqlCommand query = new SqlCommand("insert into dbo.auftrag, dbo.auftragdetails (dbo.auftrag.Kundennummer, dbo.auftrag.Name, dbo.auftrag.Strasse, dbo.auftrag.Plz, dbo.auftrag.Ort, dbo.auftrag.Land, dbo.auftragdetails.Pos, dbo.auftragdetails.Artikel, dbo.auftragdetails.Preis) Values (@Kundennummer, @Name, @Strasse, @Plz, @Ort, @Land, @Pos, @Artikel, @Preis)", con);
                query.Parameters.AddWithValue("@Kundennummer", kundennummerTextBox.Text);
                query.Parameters.AddWithValue("@Name", nameTextBox.Text);
                query.Parameters.AddWithValue("@Strasse", strasseTextBox.Text);
                query.Parameters.AddWithValue("@Plz", plzTextBox.Text);
                query.Parameters.AddWithValue("@Ort", ortTextBox.Text);
                query.Parameters.AddWithValue("@Land", landTextBox.Text);
                query.Parameters.AddWithValue("@Pos", posTextBox.Text);
                query.Parameters.AddWithValue("@Artikel", artikelTextBox.Text);
                query.Parameters.AddWithValue("@Preis", preisTextBox.Text);
                query.ExecuteNonQuery();
                MessageBox.Show("Daten gespeichert");
                con.Close();


    Beim Ausführen bekomme ich folgende Fehlermeldung:

    Ein Ausnahmefehler des Typs "System.Data.SqlClient.SqlException" ist in System.Data.dll aufgetreten.
    Zusätzliche Informationen: Falsche Syntax in der Nähe von ",".

    Wenn ich die Tabelle dbo.Auftragdetails weglasse funktioniert das ganze Einwandfrei.

    Mit freundlichen Grüßen

    Wolfgang Ruggenthaler


    Mittwoch, 21. März 2018 10:37

Antworten

  • new SqlCommand("insert into dbo.auftrag, dbo.auftragdetails (..

    Hallo Wolfgang,

    bei einem INSERT Statement kann man immer nur eine einzige Tabelle ansprechen, zwei oder mehr ist nicht möglich, deswegen bekommst Du eine Fehlermeldung. Du musst also erst die Daten in die Tabelle "Auftrag" und danach in "Auftragsdetails"; siehe INSERT (Transact-SQL)


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Mittwoch, 21. März 2018 10:47

Alle Antworten

  • new SqlCommand("insert into dbo.auftrag, dbo.auftragdetails (..

    Hallo Wolfgang,

    bei einem INSERT Statement kann man immer nur eine einzige Tabelle ansprechen, zwei oder mehr ist nicht möglich, deswegen bekommst Du eine Fehlermeldung. Du musst also erst die Daten in die Tabelle "Auftrag" und danach in "Auftragsdetails"; siehe INSERT (Transact-SQL)


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Mittwoch, 21. März 2018 10:47
  • Hallo Olaf,

    vielen Dank für deine schnelle Antwort. Ich werde mal schaun ob ich das so hinbekomme.

    Wolfgang Ruggenthaler

    Mittwoch, 21. März 2018 10:55
  • Hi Wolfgang,
    wichtig bei der Übertragung ist, die Beziehung beizubehalten.

    Die konkrete Lösung hängt davon ab, wie Du die Primärschlüssel-ID (Angebot-ID - Auftrag-ID) und die Fremdschlüssel-ID (in Angebotdetails und Auftragdetails) behandelst. Wenn beispielsweise in der Tabelle Auftrag die ID als Autowert vergeben wird, dann wird beim Insert eine neue ID vergeben. Wenn dann Datensätze in die Tabelle Auftragdetails übertragen werden, ist damit zu rechnen, dass der Fremdschlüssel nicht mehr zum Primärschlüssel passt. In diesem Fall kannst Du nicht wie von Olaf vorgeschlagen zuerst die Daten der Tabelle Angebot in die Tabelle Auftrag und danach die Datensätze aus der Tabelle Angebotdetails in die Tabelle Auftragdetails übertragen. Du musst in diesem Fall immer zuerst einen Datensatz aus Auftrag übertragen, die neue ID holen, in den dazugehörenden Angebotdetails lokal (nicht in der Datenbank) die Fremdschlüssel-ID ändern und diese Datensätze in Auftragdetails abspeichern.

    Eine alternative Lösung ist, die Autowert-Erzeugung beim Einfügen zeitweilig außer Kraft zu setzen. Damit bleiben die Werte der Primärschlüsselspalte erhalten und auch die Beziehungen zur Fremdschlüsselspalte werden nicht zerstört.

    Wenn die Primärschlüssel jedoch beim Übertragen nicht verändert werden (z.B. GUID oder kein Autowert), dann sollte der einfache Kopiervorgang die Beziehungen nicht zerstören und die von Olaf genannte Übertragung kann angewandt werden. Das funktioniert, wenn es keine weiteren Aktivitäten gibt, die auf Primärschlüssel und Fremdschlüssel einwirken (z.B. Trigger). Ohne eigenes Zutun werden keine Trigger automatisch hinzugefügt.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks





    Donnerstag, 22. März 2018 06:26
  • Hallo Peter,

    vielen Dank für deine Hilfe.

    Die AngebotID in der Tabelle Angebot und die AuftragID in der Tabelle Auftrag sind Autowerte und in den Tabellen AngebotDetails, Auftragdetails als Fremdschlüssel drinnen. Die Tabelle Angebot lässt sich anstandslos in die Tabelle Auftrag speichern, aber wie übertrage ich die AngebotDetails in die AuftragDetails? Gibt es vielleicht Beispiele die ich mir ansehen kann?

    LG Wolfgang

    Donnerstag, 22. März 2018 07:38
  • Hi Wolfgang,
    in diesem Fall gibt es verschiedene Lösungsmöglichkeiten, wenn Du die Autowert-Erstellung in der Zieltabelle (Auftrag) nicht zeitweilig ausschalten willst.

    Du musst in einer Schleife einzeln alle zu übertragenden Angebots-Datensätze holen. Für jeden Angebots-Datensatz holst Du dann die Datensätze mit den Angebotsdetails. Dann speicherst Du den Angebots-Datensatz in die Auftrags-Tabelle und holst Dir den neu vergebenen Autowert (ID-Wert). Dann trägst Du in alle geladenen Angebotsdetails die neu vergebene ID als Fremdschlüssel ein und speicherst die Datensätze in die Tabelle der Auftragdetails. Das wird für alle Angebots-Datensätze, die zu übertragen sind, ausgeführt. Nach diesem Kopiervorgang hast Du aber keine Beziehung der Auftragsinformation zur Angebotsinformation mehr. Wenn Du das später benötigst, musst Du Dir die alte Angebots-ID zusätzlich merken. Dieser geschilderte Ablauf kann mit einem DataSet mit DataRelations vereinfacht werden, da bei einem DataAdapter-Update auch alle Datensätze letztendlich einzeln abgespeichert werden und in einer Ereignisroutine auf die Änderungen (neue ID) reagiert werden kann.

    Wenn Du jedoch später eine Zugehörigkeit der Auftragsinformation zur Angebotsinformation benötigst, dann solltest über einen Transfer ohne Neuanlage der ID nachdenken. Das ist möglich über ein:

    SET IDENTITY_INSERT [ database_name . [ schema_name ] . ] table { ON | OFF }


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Donnerstag, 22. März 2018 08:54
  • Hallo Peter,

    "DataSet mit DataRelations vereinfacht werden, da bei einem DataAdapter-Update auch alle Datensätze letztendlich einzeln abgespeichert werden und in einer Ereignisroutine auf die Änderungen (neue ID) reagiert werden kann."

    Ich habe am Wochenende einiges probiert, leider hats nicht funktioniert.

    Ich habe in in der Form ein DataSet, muss ich die Angebot und AngebotDetail mit den Auftrag und AuftragDetail verknüpfen?

    LG Wolfgang

    Montag, 26. März 2018 09:13