Benutzer mit den meisten Antworten
Problem beim hinzufügen einer Tabellenspalte.

Frage
-
Guten Tag
Ich arbeite zurzeit an einem Programm für ein WM 2010 Wettbewerbsspiel.
Nun habe ich eine SQL Datenbank angelegt mit verschiedenen tabellen.
Nun habe ich das problem, das ich in der Tabele tbl_ma (Tabelle in welcher die Mitarbeiter mit Batch nur gespeichert sind) keine spalte mehr hinzufügen kann, welche "not Null" ist.
Jedesmal bekomme ich eine Fehlermeldung:
tbl_MA-Tabelle
- Tabelle kann nicht geändert werden.
Mit ALTER TABLE können nur Spalten hinzugefügt werden, die NULL-Werte enthalten können oder eine DEFAULT-Definition aufweisen. Oder die hinzugefügte Spalte ist eine identity- oder timestamp-Spalte. Falls keine der genannten Bedingungen erfüllt sind, muss die Tabelle leer sein, damit diese Spalte hinzugefügt werden kann. Die 'sf'-Spalte kann nicht der nicht leeren 'tbl_MA'-Tabelle hinzugefügt werden, da sie diese Bedingungen nicht erfüllt.Nun habe ich mich ein bisschen darüber schlau gemacht, und habe zwar den Fehler ( das ALTER TABLE lässt "NOT NULL" nicht zu. ), ABER habe ich nicht herausfinden können, wie ich dies im VS 2008 ändern kann, das ich wieder "NOT NULL" verwenden darf.
Vielen dank für die Hilfe.
Und ich Entschuldige mich schon jetzt, da ich nicht genau wusste wohin mit dieser Frage, da es mit VS, SQL und VB zu tuhn hat.
Gruss
Chris K.
- Verschoben Robert BreitenhoferModerator Donnerstag, 25. März 2010 15:42 SQL (Von:Visual Basic)
Antworten
-
Hallo Chris,
wenn bereits Daten in der Tabelle vorhanden sind (!), kannst Du ein neues Feld mit NOT NULL nur hinzufügen, wenn ein Default (Standardwert) definiert ist. Du müsstest also im Tabellen-Designer einen Standardwert setzen, z.B. 0.
Alternative wäre über T-SQL, dann könntest Du das Feld zunächst mit NULL hinzufügen, die vorhandenen Datensätze auf einen gewünschten Wert ändern (z.B. auch abhängig der vorhandenen Daten) und anschließend das Feld auf NOT NULL ändern. Beispiel:
CREATE TABLE #test (id int IDENTITY(1,1));
INSERT INTO #TEST DEFAULT VALUES;
GO
-- Per Update
ALTER TABLE #test
ADD sf int NULL;
GO
UPDATE #test
SET sf = 0
WHERE sf IS NULL;
GO
ALTER TABLE #test
ALTER COLUMN sf int NOT NULL;
-- Per Default Wert
ALTER TABLE #test
ADD sf2 int NOT NULL DEFAULT(0);
SELECT *
FROM #test;
GO
DROP TABLE #test;
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de- Als Antwort vorgeschlagen Andy Löwen Freitag, 26. März 2010 06:03
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 30. März 2010 10:03
-
Hallo Chris,
wenn Du eine Spalte mit NOT NULL erstellen willst,
so mußt Du für die Spalte einen Standardwert (DEFAULT) angeben,
denn sonst würden alle bestehenden Zeilen die NOT NULL Regel verletzen.Im Designer (Visual STudio oder Management Studio) findest Du es
unter den Eigenschaften als "Standardwert oder -bindung".Via T-SQL:
CREATE TABLE tbl_Ma ( id int not null primary key); -- Spalte die NULL Werte zulässt ALTER TABLE tbl_Ma ADD SpalteMitNull int NULL; -- Spalte ohne NULL-Werte und einem (benannten) Standardwert ALTER TABLE tbl_Ma ADD SpalteOhneNullMitDefault int NOT NULL CONSTRAINT DF_tbl_Ma_SpalteOhneNullMitDefault DEFAULT (0);
Der angegebene Standardwert muß dem Datentyp entsprechen bzw. in ihn konvertiert werden können.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 30. März 2010 10:03
Alle Antworten
-
Hallo Chris,
wenn bereits Daten in der Tabelle vorhanden sind (!), kannst Du ein neues Feld mit NOT NULL nur hinzufügen, wenn ein Default (Standardwert) definiert ist. Du müsstest also im Tabellen-Designer einen Standardwert setzen, z.B. 0.
Alternative wäre über T-SQL, dann könntest Du das Feld zunächst mit NULL hinzufügen, die vorhandenen Datensätze auf einen gewünschten Wert ändern (z.B. auch abhängig der vorhandenen Daten) und anschließend das Feld auf NOT NULL ändern. Beispiel:
CREATE TABLE #test (id int IDENTITY(1,1));
INSERT INTO #TEST DEFAULT VALUES;
GO
-- Per Update
ALTER TABLE #test
ADD sf int NULL;
GO
UPDATE #test
SET sf = 0
WHERE sf IS NULL;
GO
ALTER TABLE #test
ALTER COLUMN sf int NOT NULL;
-- Per Default Wert
ALTER TABLE #test
ADD sf2 int NOT NULL DEFAULT(0);
SELECT *
FROM #test;
GO
DROP TABLE #test;
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de- Als Antwort vorgeschlagen Andy Löwen Freitag, 26. März 2010 06:03
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 30. März 2010 10:03
-
Hallo Chris,
wenn Du eine Spalte mit NOT NULL erstellen willst,
so mußt Du für die Spalte einen Standardwert (DEFAULT) angeben,
denn sonst würden alle bestehenden Zeilen die NOT NULL Regel verletzen.Im Designer (Visual STudio oder Management Studio) findest Du es
unter den Eigenschaften als "Standardwert oder -bindung".Via T-SQL:
CREATE TABLE tbl_Ma ( id int not null primary key); -- Spalte die NULL Werte zulässt ALTER TABLE tbl_Ma ADD SpalteMitNull int NULL; -- Spalte ohne NULL-Werte und einem (benannten) Standardwert ALTER TABLE tbl_Ma ADD SpalteOhneNullMitDefault int NOT NULL CONSTRAINT DF_tbl_Ma_SpalteOhneNullMitDefault DEFAULT (0);
Der angegebene Standardwert muß dem Datentyp entsprechen bzw. in ihn konvertiert werden können.
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 30. März 2010 10:03
-
Vielen Vielen Dank!
mit dem Standart wert eingeben und dan in NOT NULL ändern hat perfekt funktioniert!Nun hätte ich noch eine Frage.
Erklährung:
In der tbl_MA (Mitarbeiter tabelle) ist Vorname, Nachname, Batchnr. und das Passwort definiert.
am Anfang ist das Passwort = die Batchnr.Nun soll aber bei der ersten Anmeldung im Programm überprüft werden, ob Passwort = Batchnr ist.
Fals dies der Fall sein sollte, wird der User aufgefordert sein Passwort zu ändern.-------------------------------------------------------------------------------------------------
Dies mit der Überprüfung habe ich hingekriergt.
jedoch bei der Änderung des passworts komme ich nicht weiter.Ich weiss, dass ich mit " INSERT INTO [TABELLE] SPALTE '" WERT "' " werte in spalten eingeben kann.
Aber ich will, das nur bei diesem usert das Passwort geändert wird, nach seinen angaben.Vielen Dank
Chris Kaiser
-
Das geht mit dem Update Befehl, z.B.
UPDATE tbl_MA
SET Passwort = ...
WHERE ...
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de -
Guten Tag
Vielen Dank für die Hilfe! =)
Ich habe es mit diesem Code versucht:
command.CommandText = "UPDATE [tbl_MA] SET Passwort = '" & mtb_newpw.Text & "' WHERE [tbl_MA] Nachname = '" & Start.tb_nachname.Text & "' AND Vorname = '" & Start.tb_vorname.Text & "' AND Nachname = '" & Start.tb_nachname.Text & "' AND Batchnr = '" & Start.mtb_passwort.Text & "'"
Jedoch funktioniert dies nicht ganz,
denn er will das in der maskedtextbox eingebene passwort nicht in die tabelle schreiben.
(mtb_newpw ist eine masked TextBox, Start.****.Text sind TextBoxen auf einer anderen Form,welche offen ist.)
- Bearbeitet Robert BreitenhoferModerator Dienstag, 30. März 2010 10:04 Formatierung
-
Hallo Chris,
zunächst solltest Du nicht mit Zeichenverkettung arbeiten, schon gar nicht in kritischen Bereichen
wie Kennwörtern, denn damit öffnest Du SQL Injection Tür und Tor.Und auch ohne den Teufelan die Wand zu malen, kriegst Du schon Probleme,
wenn ein Anführungszeichen in einem Wert vorkommt (z. B. ein Nachname wie O'Malley).
Und man verliert auch schnell den Überblick, was Dir anscheinend passiert ist,
da Du Nachname zweimal zuweist.
Eine bessere Variante (für den SqlClient):' Namen mit @...Start entsprechen den Originalwerten command.CommandText = "UPDATE [tbl_MA] SET Passwort = @Passwort " & _ "WHERE Nachname = @NachnameStart AND Vorname = @VornameStart AND Batchnr = @BatchnrStart;" ' TODO: Datentypen und Längenangaben entsprechend Tabellendefinition anpassen command.Parameters.Add("@Passwort", SqlDbType.NVarchar, 40).Value = mtb_newpw.Text command.Parameters.Add("@NachnameStart", SqlDbType.NVarchar, 40).Value = Start.tb_nachname.Text command.Parameters.Add("@VornameStart", SqlDbType.NVarchar, 40).Value = Start.tb_vorname.Text command.Parameters.Add("@BatchnrStart", SqlDbType.NVarchar, 40).Value = Start.mtb_passwort.Text
Wobei es hier günstiger und sicherer wäre, in der WHERE Bedingung auf den Primärschlüssel
der Tabelle zurückzugreifen, den Du bereits bei der Abfrage der Daten ermittelt haben solltest.
Womit die WHERE Klausel nicht nur einfacher, sondern auch verwechslungssicher ausgeführt wird.
Im übrigen ist für ein Kennwort eine Textbox mit UseSystemPasswordChar ausreichend,
die MaskedTextBox bringt dort keinen Mehrwert.Gruß Elmar
-
Hallo Chris,
Jedoch funktioniert dies nicht ganz
Das ist nicht gerade eine wirklich hilfreiche Aussage. Was funktioniert nicht, gibt es eine Fehlermeldung, wird der Datensatz nicht aktualisiert oder ... ?
In der WHERE Klausel solltest Du entweder einen Punkt zwischen Tabellen- und Feldnamen setzen oder den Tabellennamen ganz weg lassen.
Command.CommandText = "UPDATE [tbl_MA] " & _
"SET Passwort = '" & mtb_newpw.Text & "' " & _
"WHERE Nachname = '" & Start.tb_nachname.Text & "' " & _
"AND Vorname = '" & Start.tb_vorname.Text & "' " & _
"AND Nachname = '" & Start.tb_nachname.Text & "' " & _
"AND Batchnr = '" & Start.mtb_passwort.Text & "'"
Und:
SET Passwort = '" & mtb_newpw.Text
Du speicherst allen Ernstes das Passwort unverschlüsselt / nicht als Hash ab? Oh, oh.
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de -
Guten Morgen Olaf
Keine Fehlermeldung. Jedoch jetzt als ich bei WHERE das die Tabelle entfernt habe, hat es funktioniert! =)
Vielen Dank!
Und wegen der PasswortVerschlüsselung, das passwort ist nicht sehr extrem wichtig, es geht mehr darum, dass man nicht gleich anfängt für andere Leute Wetttipps abzugeben.
Aber, der Hauptgrund ist, das ich nicht weiss, wie dies funktioniert. Denn ich habe mir in den letzten 3 Tagen im Schnellgang den einfachen umgang mit SQL Befehlen, so einigermassen anzueignen versucht.
Jedoch, falls Du Zeit und Lust hättest, es mir zu erklähren, währe ich natürlich sehr erfreut!
Mit Freundlichen Grüssen
Chris Kaiser
-
Vorname, Nachname und Batchnummer sind nur die Filterbedingungen (WHERE), um den zu aktualisierenden Datensatz zu ermittlen; die Werte werden nicht gesetzt. Nur die Felder in der SET Anweisung werden aktualisiert.
Das setzt aber auch voraus, das die drei Felder zusammen Deinen Primary Key darstellen und somit auch eindeutig sind. Üblicherweise verwendet man nicht einen solchen zusammengesetzten "Natural Key", sondern verwendet eine ID (z.B. als IDENTITY die automatisch vorlaufend vergeben wird), um Daten eindeutig zu identifizieren.
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de -
Solch eine ID ist natürlich vorhanden =)
und setzt sich automatisch. (1 aufwärts zählend).
Aber ich verstehe diesen Code noch nicht ganz:
command.Parameters.Add("@Passwort", SqlDbType.NVarchar, 40).Value = mtb_newpw.Text
was macht der für eine Parameter übergabe? ist das einfach eine Aktuallisierung?
Tut mir leid, wenn ich nicht gleich verstehe. Ich bin kein richtiger Programmierer. Sondern im Netzwerk und Server berreich tätig. JEdoch habe ich eine VB schulung gehabt und habe diese Arbeit übernommen.
Vielen Dank für die Gedult.
-
Das siehst Du, wenn Du Dir noch mal den Code von Elmar ansiehst, sollte es klarer werden
Command.CommandText = "UPDATE [tbl_MA] " & _
"SET Passwort = @Passwort " & _
"WHERE Nachname = @NachnameStart " & _
"AND Vorname = @VornameStart " & _
"AND Batchnr = @BatchnrStart;"
In dem SQL Statement werden Parameter verwendet, die beginnen mit dem @ (z.B. @Passwort). Mit dem Parameters.Add wird der Wert für den Parameter gesetzt. Kann man sich so vorstellen, das die Parameter durch die Werte (wie oben mtb_newpw.Text) ersetzt werden, wobei die angesprochenen Besonderheit wie Hochkomma im Text berücksichtigt werden.
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de -
Langsam läuft es doch etwas Off Topic ...
Zum einen gibt es zum Verschlüsseln Methoden in .NET; such einfach mal im Visual Basic Forum danach, da war letztens ein Beitrag dazu. Dann kannst Du das Passwort gleich bereits verschlüsselt an den Sql Server übertragen; das wird das sicherste sein.
Passwörter speichert man i.d.R nur als Hashwert ab, damit man es nicht zurück-schlüsseln kann (auch Du als Entwickler der App nicht). Auch zur Hash-Wert Bildung gibt es Methoden in .NET; such mal nach HASH + MD5 oder SHA1.
Der Sql Server bietet dazu auch Funktionen, das heisst aber, das Du das Passwort zunächst in Klartext übertragen musst; das verringert schon mal die Sicherheit, weil man das z.B. mit dem SQL Profiler protokollieren könnte.
DECLARE @Hash as varbinary(8000)
SET @Hash = 0x0CBC6611F5540BD0809A388DC95A615B
-- Hash-Wert ermitteln
SELECT HashBytes('MD5', 'Test')
-- Prüfen, ob Passwort stimmt
SELECT CASE WHEN @Hash = HashBytes('MD5', 'Test')
THEN 'Passwort stimmt'
ELSE 'Passwort stimmt nicht'
END AS PwdValidierung
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de