hallo,
ich habe 7 Eingabefelder, 6 davon vom Typ Integer, die optional sind. In Access 2007 Datenbank sollen sie dann alle agbespeichert werden, egal ob die Eingabefelder voll oder leer sind. Und da liegt mein Problem - bei der Übertragung, die leeren Eingabeboxen erzeugen eine Fehlermeldung, egal ob ich die einer Variable übergebe, abfrage nach Inhalt und als wert null gebe, oder wenn ich mit DBNull.Value versuche. Hier ein Ausschnitt meines Codes:
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Bericht.accdb;Jet OLEDB:Database Password='xxx';");
conn.Open();
String MyString = @"INSERT INTO Prüfprotokoll " +
"(BerichtNr, AuftragsNr, Pos, Durchmesser, Wanddicke, LängeVon, LängeBis " +
"VALUES ("+ Bericht +"," +
tbAuftrag.Text + "," +
tbPosition.Text + "," +
tbDurchmesser.Text.Replace(',', '.') + "," +
tbWanddicke.Text.Replace(',', '.') + "," +
tbLängeVon.Text + "," +
tbLängeBis.Text + ")"
try
{
MessageBox.Show(MyString);
OleDbCommand cmd = new OleDbCommand(MyString, conn);
cmd.ExecuteNonQuery();
}
catch ( Exception fehlerAllgemein )
{
MessageBox.Show(fehlerAllgemein.Message);
throw fehlerAllgemein;
}
finally
{
conn.Close();
}
Hat jemand eine Idee?
Vielen Dank im voraus
Irek
Hallo i-rek,
poste bitte die Fehlermeldung die du bekommst, so können wir nur raten.
[Artikelserie] Parameter von SQL Befehlen
So wie du es machst ist es sehr fehleranfällig. Schon bei tbDurchmesser.Text.Replace(',', '.')
stehen mir die Haare zu Berge. Wenn der Wert in der Datenbank schon ein int
ist, warum convertierst du den Wert nicht nach int. Fehleingaben kannst du so ja keine mehr abprüfen. Und das Replace ist fehl am Platz. So wie ich das beurteilen kann willst du "tausend" geschriefen in folgender Form 1,000 nach 1.000 ändern. Was ist das Problem. 1.000 ist bei einem PC mit deutschem Layout tausend, beim englischen z.b. aber 1.
Ich hoffe ich konnte dir einige Denkanstöße geben.
Gruß
Michael
hallo Muro,
habe .Net in US Einstellung. Die Zahlen in Form von z.B. 3,23 werden nicht akzeptiert, sondern 3.25. Aber du hast schon recht, habe in der Beschreibung ein Fehler gemacht, sprich es sind nicht nur int-Variablen darunter, sondern auch 2 Single-Werte mit eingebauter Replace-Funktion.
Das funktioniert problemlos, nur mit den null-Werten habe ich noch keine Lösung gefunden.
irek
Danke für dein Tip,
habe jetzt alles auf Parameter umgestellt und kriege trotzdem Fehlermeldungen, egal ob ich Parameters.Add oder ParametersAddWithValue benutze.
z.B.
cmd.Parameters.AddWithValue(new OleDbParameter("@LV", tbLängeVon.Text.Length>0 ? tbLängeVon.Text : DBNull.Value));
leider ja... sogar 2 Fehler:
Ja ich weiß,
jedoch denke ich wird es sicherlich kein Problem sein Compilerfehler selbst zu lösen.
cmd.Parameters.AddWithVaulue("parametername","parameterWert");
Bezüglich ersteren Ferhler: Du kannst auch eine externe if Anweisung schreiben und nicht die Kurzschreibweise. Bei der müssen beide Konditionen den selben Datentyp haben.
Vielen Dank Michael, für die Mühe,
eine externe if-Abfrage wäre schon gut, am besten wäre sogar das Rauslassen einer Variable, wenn der Eingabefeld leer ist.
Aber da müsste auch bei der INSERT INTO -Abfrage diejenige Variable herausgenommen werden. Ich kann doch nicht weniger Parameters einfügen, als es in der INSERT Into steht, oder?
Nein kannst du nicht.
Mit einer externen if meinte ich folgendes Konstrukt:
if(tbLängeVon.Text.Length>0 )
cmd.Parameter.AddWithValue("parametername",DBNull.Value);
else
cmd.Parameter.AddWithValue("parametername",tbLängeVon.Text);
sorry,
aber das funktioniert auch nicht. Jetzt kriege ich eine Fehlermeldung:Überlauf
*Wie lang ist der Text? Wie lang darf er sein(Laut Spaltendefinition)? *Deine einzufügende Zahl ist zu groß. Integer dürfen maximal 2.147.483.647 groß sein. Wenn du größere Zahlen einzufügen planst verwende bigint.
Overflow bei Access heißt "overflow" dass das einzufügende Feld zu groß für die Spalte ist.
Ich würde dir raten mal testweise eine Tabelle mit 1-2 Spalten zu erstellen und dann ein Insert dort zu probieren.
Das habe ich schon gemacht u.a. mit reinem SQL Befehl in die Datenbank geschrieben, upgedated etc. Mein Programm will 'null' überhaupt nicht akzeptieren.
Wenn ich mir z.B. den SQL-string im Code anzeigen lasse (bevor ExecuteNonQuery ausgeführt) wo eine der Variablen 'null' ist, kriege ich ein Doppelkomma z.B.
INSERT INTO(......) VALUES(3100,23,,2000,3000,24,25)
'null' wird einfach "geschluckt" egal ob ich es direckt in die Parameters eingebe, oder DBNull.Value benutze. Ich werde wahnsinnig. 😃
Irgendwie habe ich den Eindruck, die 'null'-Eingabe muss im C#-Code aktiviert werden.
Ne blöde Frage:
Sind die Access-Spalten auf "ALLOW NULLS"?
Irgendwie habe ich den Eindruck, die 'null'-Eingabe muss im C#-Code aktiviert werden.
Nein muss sie nicht. Sollte onthefly funktionieren.
huhu,
Wenn ich mir z.B. den SQL-string im Code anzeigen lasse (bevor ExecuteNonQuery ausgeführt) wo eine der Variablen 'null' ist, kriege ich ein Doppelkomma z.B.
INSERT INTO(......) VALUES(3100,23,,2000,3000,24,25)
'null' wird einfach "geschluckt" egal ob ich es direckt in die Parameters eingebe, oder DBNull.Value benutze.
So, wie lautet denn dein aktueller SQL-Befehl? Wenn Du Parameter benutzt, dann stehen im SQL-String garantiert keine einzelnen Werte, sondern immernoch die Platzhalter. Also stimmt irgendwas von Deiner Aussage leider nicht.
desweiteren, nimm nicht den in der Textbox eingetragenen Wert - das ist ein String und kann natürlich falsch formatiert sein.
ich nehm mal den Code von oben und änder den:
if(tbLängeVon.Text.Length>0 )
cmd.Parameter.AddWithValue("parametername",DBNull.Value);
else
{
int EingabeInt;
if (int.TryParse(tbLängeVon.Text))
//Exception hier nur als Anmerkung, bitte eine Anständige Fehlerausgabe implementieren
throw new ArgumentException("Eingabe von Textbox ist kein Integer.")
else
cmd.Parameter.AddWithValue("parametername",EingabeInt);
}
😃
Xynratron
Herr, schmeiss Hirn vom Himmel - Autsch!
Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.
Hallo Xynratron,
sagte ich doch am Anfang:
Wenn der Wert in der Datenbank schon ein int ist, warum convertierst du den Wert nicht nach int. Fehleingaben kannst du so ja keine mehr abprüfen.
Wenn er in eine Integer Spalte String
statt int
einfügt und ihm dies auch noch gesagt wurde, dann werden die ein und anderen Fehler eben geworfen. Dass der String falsch formattiert sein kann und höchstwahrscheinlich auch ist wurde ihm auch schon gesagt.
[Hinweis] Wie poste ich richtig? 8
Hallo zusammen,
wollte kurz auf Eure Fragen antworten. Die Eingaben bei der int--Felder werden mit Key-Funktion abgefangen, so dass es nicht möglich ist in einem integer Feld alles außer Zahlen einzugeben.
Das hat aber nichts mit dem Problem zu tun.
Ich habe auch den INSERT-Befehl mit 'null' Werten direkt im Access ausgeführt (wie erwähnt) und die null-Werte wurden problemlos in die DB hineingeschrieben, sprich der SQL-Befehl ist richtig und somit auch "ALLOWS NULLS" ist freigeschaltet.
Ich suche auch gleichzeitig im Netz nach Lösung und leider kann ich keine Antwort finden. Manche machen sich einfacher indem sie alle Werte als String abspeichern, was für mich überhaupt nicht in Frage käme, da ich die Zahlen-Formate für spätere Abfragen und Auswertungen brauche.
Das Problem könnte ich auch mit zusätzlichen 7 Updates mit if-Abfrage zu jeder int-Variable lösen, allerdings habe ich bedenken was Geschwindigkeit angeht.
Die Eingaben bei der int--Felder werden mit Key-Funktion abgefangen, so dass es nicht möglich ist in einem integer Feld alles außer Zahlen einzugeben.
Wir sagten ja du sollst einen int einfügen. Bei:
string s = "5";
cmd.Parameter.AddWithValue("myintColumn", s);
wird eben kein int eingefügt sondern ein String. Bei
string s = "5";
int i = 0;
int.TryParse(s,out i);
cmd.Parameter.AddWithValue("myintColumn", i);
schon.
Überigens gibt es die von Xynratron genannte TryParse Überladung gar nicht
string s = "5"; int i = 0; int.TryParse(s,out i); cmd.Parameter.AddWithValue("myintColumn", i);
<klugscheißermodus>
Out-Variablen müssen nicht initialisiert werden da dies der Compiler sicherstellen muß dass die out-Variable gesetzt wird (Notfalls mit dem Defaultwert wenn keine Zuweisung in der Funktion erfolgt).
</klugscheißermodus>
/Edit: noch ein Fehler meinerseits: der Compiler setzt nicht den Defaultwert der Variablen sondern erzwingt ein Setzen der Variablen hier in int.TryParse
Hallo witte,
du hast zwar recht. Aber wenn ich den Code so geschrieben hätte dann hätte mich der ReSharper gewarnt.
Aber dies steht hier nicht zur Debatte. Wir sollten uns wieder um ursprüngliche Problem und befassen
Überigens gibt es die von Xynratron genannte TryParse Überladung gar nicht
Naja, etwas eigeninitiative darf man doch verlagen, oder? Vor allem wenn man nur mal schnell etwas Code hintippt können durchaus Fehler drin sein. Also kein Grund hier eine extra Anmerkung zu machen. Ausserdem verstehe ich Deine Anmerkung mit [Hinweis] Wie poste ich richtig? auch nicht.
😃
Xynratron
Herr, schmeiss Hirn vom Himmel - Autsch!
Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.
Ich meite mit meinem Wie poste ich richtig Punkt 8, dass er das tun sollte was man ihm vorschlägt. Und wenn man sagt er soll den String nach int konvertieren und fügt dann immer noch einen String ein, was soll man dazu sagen?
Und ich beziehe mich auch auf deinen:
So, wie lautet denn dein aktueller SQL-Befehl? Wenn Du Parameter benutzt, dann stehen im SQL-String garantiert keine einzelnen Werte, sondern immernoch die Platzhalter. Also stimmt irgendwas von Deiner Aussage leider nicht.
Denn es wurde gesagt man sollte Parameter benutzen. Laut deiner Aussage, und das ist die Tatsache, wurde dies auch nicht befolgt, was wiederum auf Punkt 8 hinführt.
ahh, Danke 😃
Herr, schmeiss Hirn vom Himmel - Autsch!
Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.
Hallo,
ich habe jetzt die Abfrage verkleinert, um den Fehler deutlich zu zeigen, den ich ständig bekomme.
**MyString="INSERT INTO Prüfprotokoll " +
"(BerichtNr, AuftragsNr, Post) " +
"VALUES (" + Bericht + "," +
"tbAuftrag.Text + "," +
DBNull.Value + ")"; ** //Könnte auch null stehen
Wenn ich vor dem Ausführen mit einer MessageBox mir den Inhalt anzeigen lasse,
kriege ich folgendes zu sehen:
INSERT INTO Prüfprotokoll (BerichtNr, AuftragsNr, Post) VALUES (31412,4784,)
Summa summarum, 'null' wird herausgeschnitten.
Den Befehl kann ich aber problemlos ausführen, wenn ich den String direkt nach tbAuftrag.Text abbreche und dann die null als Anhang hinzufüge:
MyString+=", Null)";
.... aber das ist nicht der Sinn der Sache
Das ist jetzt nicht dein ernst, oder?
Dir wird jetzt die ganze Zeit gesagt du sollst Parameter verwenden und du frickelst die sachen wieder in den SqlString.
Willst du keine Hilfe annehmen?
Willst du dein Problem nicht lösen?
DbNull.Value beim hinzufügen wird nur in Verbindung mit SqlParameter gesetzt. In deinen String-Verknüpfungen gibt DbNull.Value einen leeren String.
Entscheide dich was du verwenden willst. Entweder du erstellst deinen SqlCommand manuell oder du verwendest SqlParameter.
Wenn du nicht dies machst was wir dir vorschlagen wirst du dein Problem auch nie lösen.
Sorry, aber ich muss lachen.
Ich habe für euch sg. Experten paar Sachen umgebaut und ihr konntet das Problem nicht lösen geschweige ihr habt es verstanden, worum es geht. Statt dessen werde ich immer aufgefordert dies und jenes zu machen und mit Fragen konfrontiert, die mit dem Problem nichts zu tun haben.
Ich vergeude hier nur meine Zeit und ihr tut es auch, statt noch vieles über Programmieren zu lernen.
Nehmt es nicht persönlich, aber im großen und ganzen seid ihr nicht weiter als ein durchschnittlicher Inoformatikstudent im 2.Semester.
Nein, du bist offensichtlichg nicht in der lage simpleste Sachen zu verstehen und glaubst deswegen das diejenigen die dir immer und immer wieder die gleiche richtige Herangehensweise sagen falsch liegen.
Da das, was wir dir hier vorgeschlagen haben, in unzähligen Anwendungen funktioniert werden wir wohl recht haben.
using ( OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Bericht.accdb;Jet OLEDB:Database Password='xxx';"))
{
try
{
OleDbCommand cmd = new OleDbCommand("INSERT INTO Prüfprotokoll (BerichtNr, AuftragsNr, Pos, Durchmesser, Wanddicke, LängeVon, LängeBis) VALUES ( ?,?,?,?,?,?,? )", conn);
int value ;
if( int.TryParse( tbAuftrag.Text, out value ) )
cmd.Parameters.Add("BerichtNr", OleDbType.Integer).Value = value;
else
cmd.Parameters.AddWithValue("BerichtNr", DBNull.Value);
// für jeden Parameter
.....
conn.Open();
cmd.ExecuteNonQuery();
}
catch ( Exception fehlerAllgemein )
{
MessageBox.Show(fehlerAllgemein.Message);
throw;
}
}
Was ist so schwer daran das mal zu machen?
Da ich deine Worte nicht gelten lasse habe ich mir die Mühe gemacht und es bei mir getestet.
Ich habe folgenden Code Laufen lassen:
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\Documents\\Database1.accdb"))
{
using (OleDbCommand comm = new OleDbCommand("INSERT INTO tabelle1 VALUES (@id,@text,@zahl)", conn))
{
comm.Parameters.AddWithValue("@id", 11);
comm.Parameters.AddWithValue("@text", "5");
comm.Parameters.AddWithValue("@zahl", 6);
conn.Open();
comm.ExecuteNonQuery();
}
}
}
Acces Datenbank können leider nicht angehängt werden. Aber glaub mir, es funktioniert so.
Ist normalerweise nicht meine Art, aber hier muss ich doch wohl was zu sagen:
Sorry, aber ich muss lachen.
Ich habe für euch sg. Experten paar Sachen umgebaut und ihr konntet das Problem nicht lösen geschweige ihr habt es verstanden, worum es geht....
WIR sog.Experten haben es sehr wohl verstanden, was DEIN Problem ist und DIR auch entsprechende Lösungsvorschläge gemacht.
Statt dessen werde ich immer aufgefordert dies und jenes zu machen ... Du wurdest mehrfach 'aufgefordert', den SQL-Befehl zu parametrisieren, damit DEIN Problem elegant gelöst werden kann. Aber du hast es nicht verstanden, sondern frickelst immer noch mit zusammengestöpselten Commandstrings herum. DANN kannst DU dein Problem auch nicht lösen!!
Ich vergeude hier nur meine Zeit und ihr tut es auch,...
Deine Zeit vergeudest du selber, in dem du mit unzureichenden 'Löungen' hedrum experemntierst, anstatt die gut gemeinten Hinweise umzusetzen und auszutesten!!
Wir haben unsere Zeit in der Tat dahingehend vergeudet, Dir immer wieder zu sagen, wie Du es RICHTIG zu machen hast ==>> Parameter verwenden...
statt noch vieles über Programmieren zu lernen....
Ich glaube, DU MUSST noch viel über Programmieren lernen - uind vor allem: Dokumentationen lesen, lesen, lesen....
Nehmt es nicht persönlich, aber im großen und ganzen seid ihr nicht weiter als ein durchschnittlicher Inoformatikstudent im 2.Semester.
Vorsicht mein Guter!! Das kann man schon persönlich nehmen! Lehne dich nicht zu weit aus dem Fenster - vor allem dann nicht, wenn man nicht ansatzweise die funktionierenden Hinweise von gestandenen Programmierern annimmt und austestet!So, das musste ich mal loswerden sorry
Ich habe für euch sg. Experten paar Sachen umgebaut und ihr konntet das Problem nicht lösen geschweige ihr habt es verstanden, worum es geht
Dann hast Du's auch nicht richtig erklärt. Ich bin überzeugt, daß alle die hier versucht haben zu helfen Dein Problem entweder gar nicht bekommen oder umgehend selbständig gelöst hätten.
In diesem Sinne sin solche Aussagen wie Du sie hier tätigst eher ein Schuss ins eigene Knie.
Ich vergeude hier nur meine Zeit und ihr tut es auch,...
Dann ist es ja sicher ganz in Deinem Sinne, daß der Thread jetzt geschlossen ist.