Laden...

int=null in die Access 2007 Datenbank schreiben mit Insert Into

Erstellt von i-rek vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.183 Views
Thema geschlossen
I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren
int=null in die Access 2007 Datenbank schreiben mit Insert Into

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

1.552 Beiträge seit 2010
vor 13 Jahren

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

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

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

1.552 Beiträge seit 2010
vor 13 Jahren

Wenn du SqlParameter, wie in meinem geposteten Link gezeigt wird, verwendest dann hast du auch keine Probleme mit deinem Insert.
Ansonsten wäre eine Fehlermeldung hilfreich.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

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));

1.552 Beiträge seit 2010
vor 13 Jahren

new OleDbParameter("@LV", tbLängeVon.Text.Length>0 ? tbLängeVon.Text : DBNull.Value)

Fehlermeldung bei der Laufzeit kann nicht sein, denn das lässt sich so überhaupt nicht kompilieren.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

leider ja... sogar 2 Fehler:

  1. Type of conditional expression cannot be determined because there is no implicit conversation between 'string' and 'System.DBNull'
  2. No overload for method 'AddWithValue' takes '1' arguments
1.552 Beiträge seit 2010
vor 13 Jahren

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.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

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?

1.552 Beiträge seit 2010
vor 13 Jahren

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);

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

sorry,
aber das funktioniert auch nicht. Jetzt kriege ich eine Fehlermeldung:Überlauf

1.552 Beiträge seit 2010
vor 13 Jahren

*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.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

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.

1.552 Beiträge seit 2010
vor 13 Jahren

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.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

X
1.177 Beiträge seit 2006
vor 13 Jahren

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.

1.552 Beiträge seit 2010
vor 13 Jahren

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

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

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.

1.552 Beiträge seit 2010
vor 13 Jahren

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

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

W
955 Beiträge seit 2010
vor 13 Jahren
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

1.552 Beiträge seit 2010
vor 13 Jahren

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

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

X
1.177 Beiträge seit 2006
vor 13 Jahren

Ü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.

1.552 Beiträge seit 2010
vor 13 Jahren

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.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

X
1.177 Beiträge seit 2006
vor 13 Jahren

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.

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

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

F
10.010 Beiträge seit 2004
vor 13 Jahren

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?

1.552 Beiträge seit 2010
vor 13 Jahren

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.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

I
i-rek Themenstarter:in
12 Beiträge seit 2011
vor 13 Jahren

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.

F
10.010 Beiträge seit 2004
vor 13 Jahren

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?

1.552 Beiträge seit 2010
vor 13 Jahren

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.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

R
158 Beiträge seit 2007
vor 13 Jahren

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

Hinweis von MarsStein vor 13 Jahren

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.

Thema geschlossen