Re: Kampf mit den Möglichkeiten auf den SQL-Server zuzugreifen

Tech-Archive recommends: Fix windows errors by optimizing your registry



Reiner Wolff wrote:

Tja, irgendwie hatte ich es nicht geschafft eine Connection zu meinem
SQL-Server 2000 aufzubauen und habe dann erstmal mit der OLEDB
"angefangen".

Hi Reiner,
was hat denn nicht funbktioniert?


Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler")
Finally
cnn.Close()
Close ohne Open, wozu?

Kann demnach weg.

Der DataAdapter verläss den Zustand des Connection-Objektes so, wie er es
vorgefunden hat.

'Insert-Befehlskette basteln
strInsSQL = "Insert Into tblPerson (Nachname, Vorname,
RuTPNr, eMail) Values ( ?, ?, ?, ?)"
Beim SQL Server sollten benannte Platzhalter für die Parameter
genutzt werden.

Das funktioniert demnach auch mit OLEDB-Objekten?

Ich bin bisher nicht auf die Idee gekommen, die Möglichkeiten unpassender
Nutzung auszuloten:-) Meine Bemerkung bezog sich auf eine passende Nutzung
(über den SQLClient-Namensraum).

Warum lässt du das nicht durch den CommandBuilder machen?

Weil ich die manuelle Variante erst einmal kennenlernen wollte.

Beim CommandBuilder gibt es die Get-Methoden, die dir ein fertiges zum
SelectCommand passendes Command-Objekt liefern. Das kannst du studiren - ist
einfacher, geht schneller und funktioniert auch ohne trail and error..

Zudem sind die Textfelder bislang nicht an Datenbankfelder gebunden,
so dass eine Änderung in diesen Feldern vom CommandBuilder nicht
berücksichtigt würden. Liege ich da falsch?

Da liegst du falsch. In ADO.NET hat die Bindung einer DataSource (z.B.
DataTable) an ein Steuerelement mit dem Datenaustausch zwischen DataSource
im Client und der externen Datenbank nicht zu tun.

...
'abspeichern und neue PersonNr abfragen
Dim daNewID As New Data.OleDb.OleDbDataAdapter("Select
PersonNr From tblPerson Where Nachname = '" & rw("Nachname")
& "' And Vorname = '" & rw("Vorname") & "'", cnn)
In ds.Tables("Personen") sind doch bereist alle Personen geladen.
Wozu nochmals laden?

Es wird hier lediglich der neue Primärschlüssel abgefragt, _nicht_ der
gesamte Inhalt der Tabelle. Aus dem bereits geladenen Teil kann ich
den neuen Schlüssel nicht auslesen, da dieser erst in der Datenbank
erstellt wird.

Bei doppelten Namen und Namen mit Sonderzeichen (Apostroph, z.B. O'Neil)
geht deine Variante nicht. Mit dem SQL Server geht das ganz einfach mit
einem an Insert angehängten Select:

INSERT INTO Tab(...) VALUES(...);
SELECT * FROM Tab WHERE ID = SCOPE_IDENTITY()

Da wird der zuletzt bearbeitete Datensatz einfach zurückgelesen. Damit hast
du dann den Autowert im Client.

Eine andere Möglichkeit (z.B. bei Access) ist die Abfrage im
OnRowUpdated-Ereignis des DataAdapters.

Und das noch alles mit der Chance von SQL-Injektion.

Ah, das Thema hatten wir ja schonmal :-)

Nimm mal den Nachnamen O'Neil :-)

Liegst Du diesmal richtig?

Probiers mal mit O'Neil :-)

Geht SQL-Injektion innerhalb des SelectCommands?

Stell dir vor, die Abfrage wird in einer Login-Routine genutzt und der
Angreifer gibt ein (folgender Text mit Apostrophen eingeben!):

' OR 1=1 --'

Es kommen dann alle Datensätze und eine Abfrage, ob die Anzahl der
zurückgegebenen Datrensätze <> 0 ist, ist positiv. Damit wäre das Login
erfolgreich.

Ich weiß es nicht.

Probiers mal :-)


Dim dtNewID As
New DataTable Dim strPNrNew As String

cnn.Open()
daP.Update(dt)

Für Änderungen fehlt das Update- und Delete-Command.

Dann geht zumindest Insert, um das es bei der Bearbeitung zu dem
Programmzeitpunkt geht.
Anscheinend aber ungewöhnlich so, wa?

Eine fehlertolerante Entwicklung sollte gleich das Problem vollständig lösen
und für diesen Fall, dass DeleteCommand und UpdateCommand fehlen, das Update
entsprechend einschränken (Update nur für RowState=added).

...
'und abspeichern
'cnn.Open()

Wozu das Open?

Welches Open? Ist doch auskommentiert.

Als Kommentar ohne zusätzliche Erklärung ist so etwas völlig ungeeignet. In
ein paar Tagen/Wochen weißt du nicht mehr, was das soll. Warum dann nicht
gleich entfernen?



daAP.Update(dtA)
Auch hier fehlen Update- und Delete-Command, falls da später mal
etwas geändert wird.

Auch da würde noch der Kommentar von oben gelten.
Allerdings wäre die Frage, wie programmiert man das, wenn man nicht
nach Insert und Update trennen muss (Delete ist derzeit von der
Benutzersteuerung ausgeschlossen)?

Willst ein Update nur für RowState=modified ausführen, dann nimm im Update
nur die entsprechenden Datensätze:

myDataRowArray = myDataTable.Select(Nothing, Nothing,
DataViewRowState.ModifiedCurrent)

myDataAdapter.Update(myDataRowArray)


...
Im VS2005 bietet sich ein typisiertes DataSet mit TableAdapter für
die Vereinfachung an.

Wie sähe das denn aus bzw. wo oder wie wäre das dann einfacher?

Designer - Klicki-Klicki und fertig ist der Code, der auch gut funktioniert:

Ein mögliches Szenario könnte so aussehen:

1. im Server Explorer eine Datenverbing erstellen
2. eine Data Source erstellen. Dazu wird aus dem Server Explorer die
Verbindung genutzt und es wird die Tabelle/Abfrage ausgewählt, Das Ergebnis
ist eine typisiertes DataSet mit TableAdapter (im VS 2005).
3. DataSet-Klasse und TableAdapter im Code instanzieren, Daten mit
TableAdapter-Objekt laden (Fill-Methode) und Eigenschaften der
DataSet-Instanz für den typgerechten Zugriff auf die Daten nutzen.

...
Vor allem strukturierter Programmieren. Versuche mal jede
Funktionalität auf einer Bildschirmseite zu konzentrieren (~ 24
Zeilen).

Ja, ist inzwischen geschehen.
Schön, dass man die Prozeduren in der IDE dann auch einklappen kann.

Diese Strukturierung sollte aber nicht nur prozedural, sondern auch
klassenweise ausgeführt werden.


--
Viele Grüße

Peter


.



Relevant Pages

  • Re: Erfahrungen mit/Meinungen zu JDBC 4?
    ... @Update, wenn man UPDATE, DELETE oder INSERT, also SQL-Befehle, die kein ... insert() oder delete() auf dem DataSet auf. ... Default-Werte sind dem System auch unbekannt - man müsste ...
    (de.comp.lang.java)
  • Re: Datensatzänderung vor Edit erkennen
    ... > Kann ich für das Update des Zeitfeldes ein eigenes Commandobjekt auf ... Aber wozu die "Unübersichtlichkeit"? ... > ich die natürlich bei meinem nächsten Update auf meiner Maschine ... > gerne auch aus meinem Datagrid entfernen. ...
    (microsoft.public.de.german.entwickler.dotnet.datenbank)
  • Re: Datagrid mit OleDbDataAdapter anbinden.
    ... aber die im Datagrid vorgenommene Modifizierung der ... > die Verbindung geschlossen ist. ... > Connection.Close ist nicht erforderlich, wenn kein Open war, da Fill den ... von Update() mal ausgegeben. ...
    (microsoft.public.de.german.entwickler.dotnet.datenbank)
  • Re: insert/update trigger
    ... insert und before update trigger, um in mehreren Tabellen jedem Datensatz ...
    (microsoft.public.de.sqlserver)
  • Re: Commandbuilder update
    ... welcher Insert, Update und Delete Commands automatisch erzeugt in die ... erstelle ich jedoch in der Access DB in einem Feld z.B. Postleitzahl ... Gebe ich im DataGridView den Wert ...
    (microsoft.public.de.german.entwickler.dotnet.datenbank)