INSERT INTO soll nur fehlende Datensätze kopieren

Gotenks

Mitglied
Hallo...

bräuchte mal eure hilfe :)

Also ich möchte mittels INSERT INTO einige Datensätze in eine SQL-Tabelle hinzufügen, dass funktoniert auch wunderbar.
DOCH wenn ich öfters auf den Button klicke gibt es duplikate von den Datensätzen, weil es ya eine einfach INSERT INTO anweisung ist, gibt es irgendeine möglich, dass wenn ich auf den Button klicke, dass er nur einmal die Datensätze holt.
Und wenn ich wieder auf den Button klicke, dass er nur die neuen oder veränderten Datensätze ersetzt/ändert?
Sowas wie die Update-Anweisung? Nur mit INSERT Into****?

Freue mich über jede hilfe:
So sieht es momentan bei mir aus :)
C#:
string anweisung = String.Format("INSERT INTO BD" +
                "(ANummer,Name, BLeitzahl, BName, KNummer) VALUES" +
                "('{0}','{1}','{2}','{3}','{4}')", rows.ANummer, rows.Name, rows.BLeitzahl, rows.BName, rows.KNummer);
            using (SqlCommand cmd = new SqlCommand(anweisung, this.ZaConn))
            {
                cmd.ExecuteNonQuery();
            }

Hoffe jemand kann mir helfen :)

LG
 

Yaslaw

n/a
Moderator
Bei MySQL:
Einen Unique-Key auf die Felder setzen die eindeutig sein müssen.
Dann mittels INSERT IGNORE einfügen
SQL:
INSERT IGNORE INTO BD ......
 
Zuletzt bearbeitet von einem Moderator:

DimpiM

Mitglied
@yaslaw
damit ignorierst du nur die Datensätze aber änderst sie nicht.

@Toppic
dir wird nichts anderes Übrig bleiben als zuvor eine SELECT anweisung zu schreiben, die dir sagt ob der Datensatz schon vorhanden ist, wenn ja dann mach ein UPDATE, wenn nicht, dann mach ein INSERT
 

Gotenks

Mitglied
Danke für die ganzen Ratschläge, benutzt halt kein MySql sonder SQL normal, aber denke cih kein problem, eure ansätze aus zuprobieren :)
Danke @timestamp für den Link :)...
Doch irgendwie werde ich daraus nicht schlau...:/ wenn ich einfach das kopiere geht das, benutze aber SQL und das ist ja für MySql Gedacht?

@DimpiM
Wie würde den so ein code aussehen?
So in etwa:
C#:
Select * From test.dbo
// so und nun ich muss doch hier irgendwas eingeben wie if(bla != bla) dann erst kopieren oder updaten?

Lg
 
Zuletzt bearbeitet:

DimpiM

Mitglied
so meinte ich das
Code:
            using (SqlConnection conn = new SqlConnection("ConnectionString"))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = "SELECT * FROM BD ";
                cmd.CommandText += "WHERE ANummer = @ANummer ";
                cmd.CommandText += "AND Name = @Name ";
                cmd.CommandText += "AND BLeitzahl = @BLeitzahl ";
                cmd.CommandText += "AND BName = @BName ";
                cmd.CommandText += "AND KNummer = @KNummer ";
                cmd.Parameters.AddWithValue("@ANummer", rows.ANummer);
                cmd.Parameters.AddWithValue("@Name", rows.Name);
                cmd.Parameters.AddWithValue("@BLeitzahl", rows.BLeitzahl);
                cmd.Parameters.AddWithValue("@BName", rows.BName);
                cmd.Parameters.AddWithValue("@KNummer", rows.KNummer);
                Boolean hasRows = false;
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    if (reader.HasRows)
                        hasRows = true;
                }
                if (hasRows)
                {
                    cmd.CommandText = "UPDATE BD ";
                    cmd.CommandText += "SET Name = @Name, ";
                    cmd.CommandText += "BLeitzahl = @BLeitzahl, ";
                    cmd.CommandText += "BName = @BName, ";
                    cmd.CommandText += "KNummer = @KNummer ";
                    cmd.CommandText += "WHERE ANummer = @ANummer";
                    cmd.ExecuteNonQuery();
                }
                else
                {
                    cmd.CommandText = "INSERT INTO BD ";
                    cmd.CommandText += "(ANummer,Name, BLeitzahl, BName, KNummer) ";
                    cmd.CommandText += "VALUES (@ANummer, @Name, @BLeitzahl, @BName, @KNummer)";
                    cmd.ExecuteNonQuery();
                }
            }
wobei ich beim Update davon ausgehe, dass ANummer dein PrimaryKey ist

Nur so am Rande... Wenn du eh schon mitn SQL Server arbeitest, dann bastel dir doch StoredProcedures, dass erleichtert nicht nur das lesen des Codes, sondern die ganze Preformance, die dafür gebraucht wird um die Daten zu holen/verarbeiten usw. erledigt der SQL Server.
Falls ich irgendwas falsch sage sollten mich bitte die SQL Kenner verbessern
 

Gotenks

Mitglied
wobei ich beim Update davon ausgehe, dass ANummer dein PrimaryKey ist
jo ist okay, wobei was machst du wenn ich in excel zweimal die selbe ANummer hab, dann kommt es zu verwierrung...



dann bastel dir doch StoredProcedures, dass erleichtert nicht nur das lesen des Codes, sondern die ganze Preformance, die dafür gebraucht wird um die Daten zu holen/verarbeiten usw. erledigt der SQL Server.

habe davon garkeine Ahnung, ist ja momentan nicht notwendig, lerne ich zu einem anderen Zeitpunkt.

Zunächst einmal DANKE für den Code.

Muss ihn natürlich einwenig umändern, da sich mein code um einiges geändert hat :)

Und mal am Rande, dass ist meine Aufgabe:

-aus einer Excel Datei Werte in eine DB speichern
-in der excel datei gibt es eine spalte die ich bei der DB als PK gemacht habe, wobei das ein Fehler ist, denn bei der Excel Datei kommen die Werte die als PK sein sollen häufiger vor. z.B. 79889 <-- im Db ein PK doch wenn der öfter in der excel datei vorkommt, gibt es fehler :/

Ja also wenn ihr fragen fragen habt sagt bescheid, hoffe jmd kann verstehen was ich vor habe :)

LG

edit: wie würde dein code aussehen wenn ich mehre Spalten zunächst vergleichen möchte sprich splate 3,spalte4 und spalte 8 würde das auch gehen, also muss ich nur an einer PK spalte hängen?

So Hier ist jetzt mal mein überarbeite version.
C#:
                        using (SqlConnection Con = new SqlConnection(ConStr))
                        {
                            Con.Open();
                            SqlCommand cmd = new SqlCommand();
                            cmd.Connection = rechnungCon;
                            cmd.CommandType = CommandType.Text;

                            cmd.CommandText = "SELECT * FROM Daten ";

                            cmd.CommandText += "WHERE Bet                   = @bet "             ;
                            cmd.CommandText += "AND [Zweck 1]        = @zweck1"   ;
                            cmd.CommandText += "AND [Zweck 2]        = @zweck2"   ;
                            cmd.CommandText += "AND Fä                  = @fä "         ;
                            cmd.CommandText += "AND Freigabe               =@ freigabe

                            cmd.Parameters.AddWithValue("@betrag "          , betrag)                   ;  
                            cmd.Parameters.AddWithValue("@verwendungszweck1", verwendungszweck1)        ;
                            cmd.Parameters.AddWithValue("@verwendungszweck2", verwendungszweck2)        ;
                            cmd.Parameters.AddWithValue("@fälligkeit "      , fälligkeit)               ;
                            cmd.Parameters.AddWithValue("@freigabe "        , freigabe)                 ;
                            
                            Boolean hasRows = false;
                            using (SqlDataReader reader = cmd.ExecuteReader()) // hier kommt der fehler, siehe unten
                            {
                                if (reader.HasRows)
                                    hasRows = true;
                            }
                            if (hasRows)
                            {
                                cmd.CommandText = "UPDATE RechnungsDaten ";
                                cmd.CommandText += "SET Be                  = @be, "            ;
                                cmd.CommandText += "[Zweck 1]        = @zweck1"   ;
                                cmd.CommandText += "[Zweck 2]        = @zweck2"   ;
                                cmd.CommandText += "Fä                  = @fä "         ;
                                cmd.CommandText += "Freigabe        = @freigabe "           ;
                                

                                cmd.CommandText += "WHERE [Zweck 1] = @zweck1";
                                cmd.CommandText += "AND [Zweck 2] = @zweck2";
                                cmd.ExecuteNonQuery();
                            }
                            else
                            {
                                cmd.CommandText = "INSERT INTO RechnungsDaten ";
                                cmd.CommandText += "(Be,[Zweck Z1],[Zweck Z2],Fä)";
                                cmd.CommandText += "VALUES (@be, @zweck1, @vzweck2, @fä, @freigabe)";
                                cmd.ExecuteNonQuery();
                            }
                        }

Doch hier kommt der fehler:
Die '@Zweck1AND'-Skalarvariable muss deklariert werden.

Es ist eine FormatException... weiß aber nciht wie ich die zulösen hab, denn ich deklariere und fülle die variablen weiter oben. Ohne diesen ganzen code habe ich vorher mit einer einfachen INSERT INTo anweisung gearbeitet und dort hat es funktoniert :/

Lg
 

DimpiM

Mitglied
wenn du dir ein Breakpoint vorm ausführen (cmd.ExecuteReader()) setzt und dir den CommandText anschaust wirst du feststellen, dass zwischen @zweck1 und AND kein Leerzeichen ist, genauso wenig bei @zweck2.
Des weiteren musst du die @Variablen auch hinzufügen, eben mit cmd.Parameters.AddWithValue, wenn du sie im CommandText @bet nennst, musst du sie bei AddWithValue auch @bet nennen und nicht @betrag.
Dann musst du dem SQLCommand noch die richtige SQLConnection zuweisen...

Code:
using (SqlConnection Con = new SqlConnection(ConStr))
                        {
                            Con.Open();
                            SqlCommand cmd = new SqlCommand();
                            cmd.Connection = Con ;
                            cmd.CommandType = CommandType.Text;
 
                            cmd.CommandText = "SELECT * FROM Daten ";
 
                            cmd.CommandText += "WHERE Bet                   = @bet ";
                            cmd.CommandText += "AND [Zweck 1]        = @zweck1 ";
                            cmd.CommandText += "AND [Zweck 2]        = @zweck2 ";
                            cmd.CommandText += "AND Fä                  = @fä ";
                            cmd.CommandText += "AND Freigabe               =@freigabe";
 
                            cmd.Parameters.AddWithValue("@bet "          , betrag);  
                            cmd.Parameters.AddWithValue("@zweck1 ", verwendungszweck1);
                            cmd.Parameters.AddWithValue("@zweck2 ", verwendungszweck2);
                            cmd.Parameters.AddWithValue("@fä "      , fälligkeit);
                            cmd.Parameters.AddWithValue("@freigabe"        , freigabe);

hab mir jetzt noch nicht mehr angeschaut... waren darin schon viele Fehler. Aber vermeide beim Programmieren am besten immer Umlaute. Kann zu Fehlern kommen
 

Gotenks

Mitglied
dass zwischen @zweck1 und AND kein Leerzeichen ist, genauso wenig bei @zweck2.

Verstehe ich nicht ganz, da sind doch leerzeichen...

Des weiteren musst du die @Variablen auch hinzufügen, eben mit cmd.Parameters.AddWithValue, wenn du sie im CommandText @bet nennst, musst du sie bei AddWithValue auch @bet nennen und nicht @betrag.

Ups mein fehler, habe direkt den CVariablen namen benutzt... Sorry
Dann musst du dem SQLCommand noch die richtige SQLConnection zuweisen...

Getan! :) habe zu viele connections xD


Danke zunächst ändere mal die Fehler wobei ich nicht weiß welche Leerzeichen du meinst :)

//Edit: Verstanden :) Danke ändere mal alles und melde mich wieder.

Danke

LG
 
Zuletzt bearbeitet: