Felix_Roscher Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 (bearbeitet) Hi. Wollte mal fragen wie ich das mache wenn ich einen datensatz Löschen möchte aber der nicht mit einem festen wert mache sondern mit einer Varialbe. ich dachte ich könnte es so machen wie ich das beim Speichern gemacht habe. Hier der Code für das speichern. 'Connection erstellen / Der Connectionstring muss natürlich angepasst werden! Dim con As New Odbc.OdbcConnection(" ") 'Statement als string erstellen (Noch ergänzen! Für jeden Parameter ein Fragezeichen...) Dim sql As String = "INSERT INTO tab_spot(Eintrag_id ,Kundenname, Spotname, Sprecher1, Sprecher2, Sprecher3, Branche, Musik, Spotlaenge, Spottext, Spotbeschreibung) VALUES (?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" 'Command erstellen und diesem das SQL-Statement zuweisen! Dim cmd As New Odbc.OdbcCommand(sql) 'Parameter erstellen (100 ist hier die Feldgröße also anpassen!) Dim paramEintrag_id As New OdbcParameter("@eintrag_id", OdbcType.VarChar, 100) Dim paramKundenname As New OdbcParameter("@kundenname", OdbcType.VarChar, 100) Dim paramSpotname As New OdbcParameter("@spotname", OdbcType.VarChar, 100) Dim paramSprecher1 As New OdbcParameter("@sprecher1", OdbcType.VarChar, 100) Dim paramSprecher2 As New OdbcParameter("@sprecher2", OdbcType.VarChar, 100) Dim paramSprecher3 As New OdbcParameter("@sprecher3", OdbcType.VarChar, 100) Dim paramBranche As New OdbcParameter("@branche", OdbcType.VarChar, 100) Dim paramMusik As New OdbcParameter("@musik", OdbcType.VarChar, 100) Dim paramSpotlaenge As New OdbcParameter("@spotlaenge", OdbcType.VarChar, 100) Dim paramSpotbes As New OdbcParameter("@spotbes", OdbcType.VarChar, 100) Dim paramSpottext As New OdbcParameter("@spottext", OdbcType.VarChar, 100) 'Hier werden Parameter hinzugefügt was wesentlich sicherer und im SQL-String einfacher zu handhaben ist 'Hinzufügen der Parameter zum Command (Hier ist die Reihenfolge WICHTIG!) cmd.Parameters.Add(paramEintrag_id).Value = txtknr.Text cmd.Parameters.Add(paramKundenname).Value = txtkname.Text cmd.Parameters.Add(paramSpotname).Value = txtspname.Text cmd.Parameters.Add(paramSprecher1).Value = txtsp1.Text cmd.Parameters.Add(paramSprecher2).Value = txtsp2.Text cmd.Parameters.Add(paramSprecher3).Value = txtsp3.Text cmd.Parameters.Add(paramBranche).Value = cmdbra.Text cmd.Parameters.Add(paramMusik).Value = txtmus.Text cmd.Parameters.Add(paramSpotlaenge).Value = txtspl.Text cmd.Parameters.Add(paramSpotbes).Value = txtkbez.Text cmd.Parameters.Add(paramSpottext).Value = txtsptex.Text Dim transaction As OdbcTransaction Dim affectedRows As Integer = 0 Try 'Verbindung zur DB öffnen con.Open() transaction = con.BeginTransaction(IsolationLevel.ReadCommitted) cmd.Connection = con cmd.Transaction = transaction 'Command ausführen affectedRows = cmd.ExecuteNonQuery() 'Verbindung wieder schliessen transaction.Commit() con.Close() MessageBox.Show(String.Format("Es wurden {0} Datensätze eingefügt.", affectedRows.ToString())) Catch ex As Exception MsgBox(ex.Message) Finally con.Close() End Try ich wollte die INSERT INTO zeile durch die zeile ersetzen: DELETE tab_spot(Eintrag_id ,Kundenname, Spotname, Sprecher1, Sprecher2, Sprecher3, Branche, Musik, Spotlaenge, Spottext, Spotbeschreibung)WHERE Eintrag_id = " ich weiß nur nicht was ich nach dem = schreiben soll. kann mir da jemand helfen??? Bearbeitet 7. Dezember 2009 von Felix_Roscher Zitieren
Sturm Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 Zuerst einmal: Die Syntax deines DELETE-Befehls ist falsch. Siehe: SQL DELETE FROM Ich verstehe dein Problem nicht ganz... Was hindert dich daran, hinter dem DELETE-String einfach eine Variable anzuhängen, die eine Eintrags-ID beinhaltet? Zitieren
Felix_Roscher Geschrieben 7. Dezember 2009 Autor Geschrieben 7. Dezember 2009 naja ich weiß nicht wie ich das mit der Variablen mache kann ich da einfach hinschreiben: Eintrag_id = txtknr? also txtknr isr die Textbox in der dann die ID drinsteht. Zitieren
Sturm Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 Probier mal "Eintrag_id = txtknr.text" aus. Zitieren
Felix_Roscher Geschrieben 7. Dezember 2009 Autor Geschrieben 7. Dezember 2009 geht leider nicht da kommt eine Fehler meldung die sagt: Unknown Table 'txtknr' in where Clausl. was meinen die damit? mein englisch ich nä,lich echt ******e. Zitieren
Sturm Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 Du musst es so machen: "DELETE FROM tab_spot WHERE Eintrag_id = " & txtknr.text & ";" Beachte die Anführungszeichen! txtknr.text gehört nicht zum SQL-Statement, sondern zum Programm. Ich habe jetzt das "&" als Verbindungszeichen zweier Strings benutzt- ich hoffe das stimmt so... Zitieren
Felix_Roscher Geschrieben 7. Dezember 2009 Autor Geschrieben 7. Dezember 2009 geht immer noch nicht jetzt sagt er das die &-Zeichen eine falsche Syntax sind. Zitieren
Sturm Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 Ich habe jetzt das "&" als Verbindungszeichen zweier Strings benutzt- ich hoffe das stimmt so... Dann ist diese Annahme wohl falsch. Zitieren
LadyPreis Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 dann poste mal bitte dein Statement, wie es aktuell aussieht. Denn eigentlich ist das &-Zeichen das Richtige, um Strings zu verketten Zitieren
Argbeil Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 Mach es doch direkt über den Table Adapter. Du kannst deine Row aus der DataTable direkt im Code über myTable.Select("Eintrag = XY") oder per Linq über "from row in table.Rows where row.Eintrag == XY select row;" auswählen. Auf die selektierte Row machst du ein row.Delete(); Danach kannst du auf deinen TableAdapter oder auf den DataAdapter Update aufrufen um die Daten mit der Datenbank zu synchronisieren. Vorteil: weniger Code, kein SQL. Die Variante in der du die Einschränkung aus dem Textfeld nimmst ist eine potentielle Sicherheitslücke für SQL-Injection. Wenn jemand in die Textbox nichts tippt löscht er ansonsten ALLE Datensätze, wenn jemand "; DELETE FROM tab_spot; eingibt ist die komplette Tabelle weg, du solltest also mindestens mit Parametern arbeiten. Zitieren
Argbeil Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 (bearbeitet) Ich lese hier immer wieder von SQL-Statements die von Hand über String-Concatenation zusammengebaut werden. Achtung: Das hat mehrere gravierende Nachteile und ist unnötig. Bevor man mit so was loslegt sollte man sich mit ADO.NET, also der Datenbankschnittstelle im .NET Framework beschäftigen, empfehlenswert ist hier z.B. das Buch ADO.NET Core Reference von MS-Press. Zu den Nachteilen der Statement-Selbstbau-Version: Der Compiler kann syntaktische Fehler in eurem SQL-Code nicht validieren.Das Resultset kann evtl. nicht automatisch an ein Formular bzw. eine WebPage gebunden werdenEs findet keine Typ-Validierung stattEs gibt keine Validierung falls bei einer DELETE/UPDATE Anwendung die Daten bereits von einem anderen User geändert wurdenFür jede CRUD Operation muss viel Code geschrieben werdenSicherheitslücke: Wenn jemand sowas wie DELETE FROM Tabelle where + txtboxDaten.Text schreibt, kann man in der Textbox jedes beliebige SQL Kommando gegen die Datenbank absetzen! Wenn ich in die Box ein ; DELETE FROM Tabelle; eingebe wird daraus folgendes SQL Kommando: DELETE FROM Tabelle where; DELETE FROM Tabelle; Je nach Datenbank wird das erste Statement mit einem Fehler quittiert, das zweite aber wird trotzdem ausgeführt und löscht die komplette Tabelle!! An der Stelle MUSS man mit SqlParameter Objekten arbeiten, alles andere wäre grob Fahrlässig! Es folgt ein grober Crash-Kurs wie man in VS2008 mit einem SQL Server viel leichter an die Daten kommt (geht auch mit anderen DBs, für Oracle müssen dafür z.B. die kostenlosen ODP.NET Tools installiert werden, auch MySQL und so gut wie jeder andere Hersteller bietet solche Provider an). Der Crash Kurs macht das lesen einer guten ADO.NET Einführung auf keinen Fall überflüssig. Es gibt auch noch andere Möglichkeiten, ich zeige hier nur eine. 1. VS starten, neues Windows Forms Projekt erstellen (Projekttyp ist eigentlich egal, es geht mit jedem Projekt) 2. Auf Ansicht->Serverexplorer gehen, Rechtsklick auf Datenverbindungen, neue Verbindung erstellen. 3. Verbindungsdaten eintragen (Achtung, SQL-Server Authentifizierung ist unsicher, besser Windows-Authentifizierung, wenn das nicht geht euren Admin ansprechen!) 4. Mit Klick auf Testverbindung prüfen ob es geht, wenn nicht anpassen. Dann auf OK klicken. 5. Im VS-Menü oben auf Daten->Neue Datenquelle hinzufügen klicken, Datenbank wählen. 6. Eure gerade erstelle Verbindung wählen, unten auf JA klicken (hierdurch wird in die app.config der Datenbank-Connection String hinzugefügt, aufpassen wenn Passwörter hinterlegt sind, bei Windows-Authentifizierung steht hier praktischerweise kein Passwort) 7. Im nächsten Schritt kann man dem ConnectionString in der app.config einen Namen geben, in meinem Falle z.B. AdventureWorksConnectionString 8. Jetzt die benötigten Tabellen, Views und StoredProcs wählen, in meinem Fall der AdventureWorks DB z.B. die Tabellen Adress und AdressType. Im unteren Bereich des Fensters kann man dem Dataset einen Namen geben, bei mir z.b. AdventureWorksDataSet. Dann auf "fertig stellen" klicken. 9. Dem Projekt wurde jetzt eine app.config mit den Connection-Infos hinzugefügt und ein AdventureWorksDataSet (kann man per Doppelklick im Projektmappen-Explorer öffnen) 10. Wenn ihr das Dataset öffnet, erscheint ein (schicker) Designer. Hier seht ihr eure Datenstruktur. Diese Struktur kann jetzt auch vom Compiler validert werden, in den Eigentschaften der Spalten finden sich z.B. auch Informationen zum Datentyp. Zu jeder Tabelle wurde ein TableAdapter generiert, dieser verbindet die erzeugten Strukturen mit der echten Datenbank aus der app.config. Per Default werden Fill & GetData Methoden erzeugt. 11. Per Rechtsklick auf die Methoden kann man Datenvorschau zum testen wählen. Auch per Rechtsklick kann man Abfragen hinzufügen. Es macht z.B. nicht immer Sinn ALLE Adressen zu laden, um eine Methode zu erstellen die Alle Adressen aus einer bestimmten City lädt macht man folgendes: 11a) Rechtsklick auf die Fill, GetData() Methode des AdressTableAdapter, Abfrage hinzufügen wählen. 11b) SQL-Anweisungen verwenden, weiter, Select Anweisung die Zeilen zurückgibt, weiter. 11c) Der Wizard erzeugt ein: SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode, rowguid, ModifiedDate FROM Person.Address wir machen daraus ein: SELECT AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode, rowguid, ModifiedDate FROM Person.Address WHERE City = @City Über den Button Abfrage-Generator kann die Abfrage getestet werden, eine gültige Stadt ist z.B. Berlin 11d) Weiter klicken, als Namen vergebe ich FillByCity und GetDataByCity, fertig stellen anklicken. 12. Jetzt können wir mit Code loslegen, laden aller Adressen geht so: (zuerst using einfügen, normalerweise using projektname.AdventureWorksDataSetTableAdapters;) // Unser Datenlieferant mit Verbindung zur Datenbank: AddressTableAdapter adressAdapter = new AddressTableAdapter(); // Leere Adressen Tabelle im Speicher anlegen: AdventureWorksDataSet.AddressDataTable adressesTable; // Laden aller Daten... adressesTable = adressAdapter.GetData(); // oder laden aller Adressen aus Berlin adressesTable = adressAdapter.GetDataByCity("Berlin"); // durchlaufen der Adressen foreach (AdventureWorksDataSet.AddressRow row in adressesTable) { // Jede Stadt anzeigen... MessageBox.Show(row.City); } // Alle mit PLZ 141111 nach Ratingen verschieben.... foreach (AdventureWorksDataSet.AddressRow row in adressesTable.Select("PostalCode = 14111")) { row.City = "Ratingen"; } // Es wurden jetzt nur die geladenen Datensätze im Speicher geändert, um die Änderungen // in die Datenbank zu schreiben: adressAdapter.Update(adressesTable); // Weil wir auf der CeBit keinen Parkplatz bekommen haben löschen wir jetzt alle Einträge aus Hannover... // Laden... adressesTable = adressAdapter.GetData(); // Zum löschen markieren... foreach (AdventureWorksDataSet.AddressRow row in adressesTable.Select("City = 'Hannover'")) { row.Delete(); } // In der Datenbank löschen... adressAdapter.Update(adressesTable); 13. Einfach oder? Um alle Daten in einem Grid anzuzeigen zieht man einfach ein DataGridView auf das Form und lässt, z.b. im Konstruktor folgenden Code ausführen: AddressTableAdapter myAdapter = new AddressTableAdapter(); this.dataGridView1.DataSource = myAdapter.GetData(); 14. Wurden Daten im Grid geändert kann man z.B. so wieder speichern: myAdapter.Update((AdventureWorksDataSet.AddressDataTable)this.dataGridView1.DataSource); Bearbeitet 7. Dezember 2009 von Argbeil Zitieren
Sturm Geschrieben 7. Dezember 2009 Geschrieben 7. Dezember 2009 Danke für den Beitrag, Argbeil.. Du hast natürlich Recht, Stringverkettung ist nicht der optimale Weg. Zitieren
Felix_Roscher Geschrieben 9. Dezember 2009 Autor Geschrieben 9. Dezember 2009 danke für eure hilfe aber ich habe es einfach so gemacht. habe einfach nach den = ein ? gesetzt als Platzhalter und es läuft super. aber trotzdem danke. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.