Avatar billede cogitans Nybegynder
06. april 2006 - 15:09 Der er 24 kommentarer og
1 løsning

Eksempel på UPDATE ved OleDB

Jeg har en AccessTabel, hvor jeg udtrækker data fra. Det viser jeg i nogle almindelige textboxe. Så kan der rettes i boxene, trykkes på en knap, og tabellen skulle opdateres med de nye data.
Når data ER hentet ind, prøver jeg sådan her:

string connection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("") + "\\_Status.mdb";
        string sqlString = "UPDATE T_Status SET Prioritet=@Prioritet, Program=@Program, Omraade=@Omraade, Tekst=@Tekst, Status=@Status, Konsekvens SQL=@Konsekvens SQL, Udviklingstid=@Udviklingstid, Pris=@Pris, Bemaerkning=@Bemaerkning WHERE F_Id=" + int.Parse(DetailsView1.Rows[0].Cells[1].Text.ToString());

        OleDbConnection con = new OleDbConnection(connection);//`
        OleDbCommand command = new OleDbCommand(sqlString, con);
        try
        {
            con.Open();
            command.ExecuteNonQuery();
        }
        catch (Exception exc)
        {
            Console.WriteLine("Fejl: " + exc.Message + " " + exc.InnerException);
        }
        finally
        {
            con.Close();
        }

Fejlen er vist noget med datamismatch. Men datatyperne stemmer godt nok overens med dem i tabellen.
Nu klager den også over, at datatypeargument ikke kan være null.

Hvad har jeg gjort forkert, og findes der et simpelt eksempel, med alm. textboxe som opdateringskilder, som jeg kan se?
Avatar billede cogitans Nybegynder
06. april 2006 - 15:14 #1
Glem den fejl med datatypearg - det har jeg løst.
Det ser ud som om, den anden fejl skyldes denne linie:
int a = adapter.Update(dset);   
Jeg prøver jo at opdatere min accessTabel gennem en OleDbAdapter, men ved UPDATE vil den have nogle argumenter med in, som jeg faktisk ikke har, eftersom de opdaterede data ligger i textboxe.
Avatar billede arne_v Ekspert
06. april 2006 - 15:17 #2
jeg kan ikke se hvor du definerer de parametre som optraeder i SQL strengen !?!?
Avatar billede arne_v Ekspert
06. april 2006 - 15:23 #3
command.Parameters.Add("@xxxx", OleDbType.VarChar, 50);
command.Parameters["@xxxx"].Value = tb.Text;

eller noget lignende
Avatar billede arne_v Ekspert
06. april 2006 - 15:31 #4
Access og OleDb er det ioevrigt ikke "?" og ikke "@" ?
Avatar billede cogitans Nybegynder
06. april 2006 - 16:21 #5
Jeg bruger Visual Studio 2005 (hvis det skulle have indflydelse på forståelsen).
I mellemtiden har jeg også ændret lidt på det. Nu ser det således ud:

try
        {
            string strConnection;
            string strSQL;
            OleDbConnection objConnection;
            strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("") + "\\_Status.mdb";
            objConnection = new OleDbConnection(strConnection);
            objConnection.Open();
            bool tekst5 = false;
            if (TextBox5.Text.ToString() == "Udført")
                tekst5 = true;
            else
                tekst5 = false;
            strSQL = "UPDATE T_Status SET 'Prioritet'=" + TextBox1.Text.ToString() + ", 'Program'='" + TextBox2.Text.ToString() + "', 'Tekst'='" + TextBox3.Text.ToString() + "', 'Status'='" + TextBox4.Text.ToString() + "', 'Konsekvens SQL'='" + tekst5.ToString() + "','Udviklingstid'='" + TextBox6.Text.ToString() + "', 'Pris'='" + TextBox7.Text.ToString() + "' WHERE F_Id=" + Request.QueryString.Get("F_Id");
            OleDbDataAdapter adapter = new OleDbDataAdapter(strSQL, objConnection);
            DataSet dset = new DataSet();
            dset.Tables.Add("T_Status");
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox1.Text.ToString(), 0);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox2.Text.ToString(), 1);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox3.Text.ToString(), 2);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox4.Text.ToString(), 3);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox5.Text.ToString(), 4);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox6.Text.ToString(), 5);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox7.Text.ToString(), 6);
        //    int temp = adapter.SelectCommand.ExecuteNonQuery();
            System.Diagnostics.Debug.WriteLine("UPDATE er: "+strSQL);
            adapter.UpdateCommand.CommandText = strSQL;
            int a = adapter.Update(dset);                          //UpdateCommand.ExecuteNonQuery();
            objConnection.Close();
            DataView objDataView = dset.Tables[0].DefaultView;
            for (int g = 0; g < 10; g++ )
                System.Diagnostics.Debug.WriteLine("index g: " + objDataView.Table.Rows[0][g].ToString());
            int pri = int.Parse(objDataView.Table.Rows[0][1].ToString());
            string pro = objDataView.Table.Rows[0][2].ToString(), tekst = objDataView.Table.Rows[0][3].ToString(), status = objDataView.Table.Rows[0][4].ToString(), udv = objDataView.Table.Rows[0][6].ToString(), pris = objDataView.Table.Rows[0][7].ToString();
            /*TextBox1.Text =
            TextBox2.Text =
            TextBox3.Text = ;
            TextBox4.Text = ;*/
            TextBox5.Text = objDataView.Table.Rows[0][5].ToString();
            TextBox6.Text = objDataView.Table.Rows[0][9].ToString();
            TextBox7.Text = objDataView.Table.Rows[0][10].ToString();
            System.Diagnostics.Debug.WriteLine("textbox9 er: " + objDataView.Table.Rows[0][8].ToString());
            System.Diagnostics.Debug.WriteLine("textbox10 er: " + objDataView.Table.Rows[0][9].ToString());
            System.Diagnostics.Debug.WriteLine("textbox11 er: " + objDataView.Table.Rows[0][10].ToString());
            System.Diagnostics.Debug.WriteLine("textbox12 er: " + objDataView.Table.Rows[0][11].ToString());
        }
        catch(Exception exc){
            System.Diagnostics.Debug.WriteLine("\nFejlen er: "+exc.Message.ToString());
        }
Avatar billede cogitans Nybegynder
06. april 2006 - 16:21 #6
...der er lige noget ekstra fyld i den førsendte kode, da jeg ved en fejl ikke nåede at fjerne alt min testkode...
Avatar billede cogitans Nybegynder
06. april 2006 - 19:10 #7
Hvad mener du helt nøjagtig i 06/04-2006 15:31:40?
Vil det i 06/04-2006 15:31:40 sige, at man kan gå ind og opdatere dele af en tabel på en så simpel måde? Eller er det ikke tabellen, man arbejder på i de eksempler?
Avatar billede arne_v Ekspert
07. april 2006 - 01:53 #8
eksempel:

        OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Databases\MSAccess\Test.mdb");
        con.Open();
        OleDbCommand ins = new OleDbCommand("INSERT INTO files VALUES (?, ?)", con); // <----
        ins.Parameters.Add("@filename", OleDbType.VarChar);
        ins.Parameters.Add("@content", OleDbType.LongVarChar);
        string[] filenames = Directory.GetFiles(@"C:\scripts", "*.bat");
        for(int i = 0; i < filenames.Length; i++)
        {
            StreamReader sr = new StreamReader(filenames[i]);
            string content = sr.ReadToEnd();
            sr.Close();
            ins.Parameters["@filename"].Value = filenames[i];
            ins.Parameters["@content"].Value = content;
            ins.ExecuteNonQuery();
        }
        con.Close();
Avatar billede arne_v Ekspert
07. april 2006 - 01:54 #9
matchningen mellem navne og spørgsmålstegn sker så på rækkefølge
Avatar billede cogitans Nybegynder
07. april 2006 - 10:25 #10
Det sidste eksempel giver mening. PRoblemet er bare, at det er INSERT og ikke UPDATE.

Jeg har udraderet nogle fejl i min kode, og er nu nået helt frem til selve opdateringen. Det benytter jeg en OleDbCommandBuilder m.m. til, men det fungerer ikke.
Ekserkveringen kommer til denne kodestump:

            OleDbCommandBuilder ObjBuilder = new OleDbCommandBuilder(adapter);
            adapter.UpdateCommand = ObjBuilder.GetUpdateCommand();
            adapter.Update(dset, "T_Status");

Og hele koden ser således ud:

OleDbDataAdapter adapter;
DataSet dset;

protected void Button1_Click(object sender, EventArgs e)
    {
        try
        {
            string strConnection;
            string strSQL;
            OleDbConnection objConnection;
            strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("") + "\\_Status.mdb";
            objConnection = new OleDbConnection(strConnection);
            objConnection.Open();
            bool tekst5 = false;
            if (TextBox5.Text.ToString() == "Udført")
                tekst5 = true;
            else
                tekst5 = false;
            strSQL = "UPDATE T_Status SET 'Prioritet'=" + TextBox1.Text.ToString() + ", 'Program'='" + TextBox2.Text.ToString() + "', 'Tekst'='" + TextBox3.Text.ToString() + "', 'Status'='" + TextBox4.Text.ToString() + "', 'Konsekvens SQL'='" + tekst5.ToString() + "','Udviklingstid'='" + TextBox6.Text.ToString() + "', 'Pris'='" + TextBox7.Text.ToString() + "' WHERE F_Id=" + Request.QueryString.Get("F_Id");
            adapter = new OleDbDataAdapter(strSQL, objConnection);
            dset.Tables.Add("T_Status");
            DataRow[] objRows;
            objRows = dset.Tables[0].Select();
            objRows[0]["Prioritet"] = TextBox1.Text.ToString();
            System.Diagnostics.Debug.WriteLine("objrows: " + objRows[0]["Prioritet"].ToString());
            objRows[0]["Program"] = TextBox2.Text.ToString();
            objRows[0]["Tekst"] = TextBox3.Text.ToString();
            objRows[0]["Status"] = TextBox4.Text.ToString();
            objRows[0]["Konsekvens SQL"] = TextBox5.Text.ToString();
            objRows[0]["Udviklingstid"] = TextBox6.Text.ToString();
            objRows[0]["Pris"] = TextBox7.Text.ToString();
            OleDbCommandBuilder ObjBuilder = new OleDbCommandBuilder(adapter);
            adapter.UpdateCommand = ObjBuilder.GetUpdateCommand();
            adapter.Update(dset, "T_Status");
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox1.Text.ToString(), 0);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox2.Text.ToString(), 1);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox3.Text.ToString(), 2);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox4.Text.ToString(), 3);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox5.Text.ToString(), 4);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox6.Text.ToString(), 5);
            dset.Tables["T_Status"].Rows[0].ItemArray.SetValue(TextBox7.Text.ToString(), 6);
            System.Diagnostics.Debug.WriteLine("UPDATE er: "+strSQL);
            adapter.UpdateCommand.CommandText = strSQL;
            int a = adapter.Update(dset);                       
            objConnection.Close();
            DataView objDataView = dset.Tables[0].DefaultView;
            int pri = int.Parse(objDataView.Table.Rows[0][1].ToString());
            string pro = objDataView.Table.Rows[0][2].ToString(), tekst = objDataView.Table.Rows[0][3].ToString(), status = objDataView.Table.Rows[0][4].ToString(), udv = objDataView.Table.Rows[0][6].ToString(), pris = objDataView.Table.Rows[0][7].ToString();
            TextBox5.Text = objDataView.Table.Rows[0][5].ToString();
            TextBox6.Text = objDataView.Table.Rows[0][9].ToString();
            TextBox7.Text = objDataView.Table.Rows[0][10].ToString();
        }
        catch(Exception exc){
            System.Diagnostics.Debug.WriteLine("\nFejlen er: "+exc.Message.ToString());
        }
    }
Avatar billede cogitans Nybegynder
07. april 2006 - 11:26 #11
Nu har jeg lavet et forsøg med data fra 07/04-2006 01:53:37.
Nu ser koden således ud:

try {
            OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("") + "\\_Status.mdb");
            con.Open();
            OleDbCommand ins =
                new OleDbCommand("UPDATE T_Status SET 'Prioritet'='"+TextBox1.Text.ToString()+
                "', 'Program'='"+TextBox2.Text.ToString()+
                "', 'Tekst'='"+TextBox3.Text.ToString()+
                "', 'Status'='"+TextBox4.Text.ToString()+
                "', 'Konsekvens SQL'='"+TextBox5.Text.ToString()+
                "', 'Udvilingstid'='"+TextBox6.Text.ToString()+
                "', 'Pris'='"+TextBox7.Text.ToString()+"' WHERE 'F_Id'=35", con);
            ins.ExecuteNonQuery();
            con.Close();
        }
        catch(Exception exc){
            System.Diagnostics.Debug.WriteLine("Fejlen er: "+exc.Message);
        }

I Output giver det:

A first chance exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Fejlen er: Der er ikke angivet nogen værdi for en eller flere krævede parametre.

Så det tyder mere og mere på, at jeg ikke har den korrekte tilgang til tabellen. Men jeg har været inde og kigge. Og det ser kun ud til, at det er primærnøglen, som er påkrævet. Og da det er primærnøglen, der står efter WHERE, skulle dette vel ikke have nogen betydning?

Deresterende felttyper inde i tabellen er:
tal
tekst
notat
ja/nej

Det eneste jeg kan se som et muligt problem, er den boolske værdi. Den bliver blot sat ind i UPDATEsql'en som "false" eller "true". Men er dette ikke den rigtige måde, at gøre det på?
Avatar billede cogitans Nybegynder
07. april 2006 - 11:41 #12
Ved alle felter, bortset fra primærnøglen, står der henholdsvis "TilladNullLængde=ja" og "obligatorisk="nej". Så det ser da fint nok ud...?
Avatar billede cogitans Nybegynder
07. april 2006 - 11:53 #13
Jeg ved ikke, om fejlen kan skyldes dette, men jeg har lige opdaget, at hvis jeg udskriver teksten inde fra textboxene inde i codebehind, så har de stadig værdien fra udtrækket. Altså ikke den opdaterede værdi. Hvordan kan dette lade sig gøre?
Avatar billede cogitans Nybegynder
07. april 2006 - 12:25 #14
'Prioritet' inde i tabellen har: Feltstørrelse="Dobbelt Reelt Tal" og "stadartværdi"=99. Skulle dette have nogen indflydelse?
Jeg kan nemlig heller ikke få lov til at fyre
UPDATE T_Status SET "Prioritet"=6 WHERE "F_Id"=35;
så kommer den frem med en popupbox, hvor man skal skrive 'Prioritet'. Når man så f.eks. skriver 6, så skriver den, at "Dette udtryk er stavet forkert, eller det forekommer for komplekst til at blive evalueret."
Avatar billede cogitans Nybegynder
07. april 2006 - 13:41 #15
Efter lidt rettelse, ser situationen nu således ud:

Når jeg kører programmet, så giver det en fejl til sidst, og tabellen bliver ikke opdateret. Fejlen er:

A first chance exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Fejlen er: Der er ikke angivet nogen værdi for en eller flere krævede parametre.

Men jeg skriver også sql'en ud inde fra codebehinden. Og hvis jeg kopierer den over i Access, og kører den dér, så går den fint ind, og retter posterne.
Hvor kan fejlen være?
Avatar billede arne_v Ekspert
08. april 2006 - 02:36 #16
re 12:25:10

der skal ike "" omkring feltnavne

re 13:41:42

må vi se SQL'en ?
Avatar billede cogitans Nybegynder
08. april 2006 - 13:24 #17
Jeg har ikke sql'en ved mig lige p.t., men er det egentlig ikke ligemeget, når nu sql'en virker inde i Access? Jeg har bare taget sql'en derinde fra og kopieret den over i sql-strengen...
Avatar billede cogitans Nybegynder
08. april 2006 - 15:44 #18
Men angående den exception, der kommer, så har jeg læst, at den kun fremkommer, når serveren eller datakilden afbryder forbindelsen til klienten. Så kan det ikke være, at serveren eller selve databasefilen ikke er konfigureret korrekt i denne situation?
Avatar billede arne_v Ekspert
08. april 2006 - 17:39 #19
nej - driveren kan godt have andre reserverede ord end Access GUI

----

OLE DB fejlmeddelser er noget af det mest mystiske på denne jord

umiddelbart tolker jeg den som om at driveren mener at du mangler at Add'e
en Parameter
Avatar billede cogitans Nybegynder
10. april 2006 - 09:02 #20
Sql'en er:
UPDATE T_Status SET Prioritet=6, Program='program1', Tekst='Mulighed for indtastning af anden forhandler', Status='Udført', KonsekvensSQL=True, Udviklingstid='a', Pris='a' WHERE F_Id=35;

Ved exceptioncatch har jeg udskrevet fejlen, som er:
"Fejlen er: Der er ikke angivet nogen værdi for en eller flere krævede parametre."

Længere nede i koden, hvor jeg stadig har min tidligere implementering, bliver der også grebet en fejl. Den lyder:
"Fejlen er: Column 'KonsekvensSQL' does not belong to table Table."
Avatar billede cogitans Nybegynder
10. april 2006 - 09:19 #21
Nu har jeg lavet en knap, hvor der bliver opdateret automatisk inde i en anden database. Og her fungerer alt selvfølgelig fint. Så jeg tror lige, at jeg skal gå koden lidt efter. Det undrer mig også, hvorfor teksten i tekstfelterne ikke bliver udskrevet med det opdaterede i console, når jeg har rettet dem...
Avatar billede cogitans Nybegynder
10. april 2006 - 09:35 #22
Det lader til, at siden ikke rigtig fanger ændringerne i tekstbox'ene. Hvis jeg udskriver indholdet af en tekstbox, så skrives indholdet ud, der stod i tekstboxen FØR opdateringen - altså ikke det, jeg lige har skrevet manuelt. Hvordan kan dette ske?
Avatar billede cogitans Nybegynder
10. april 2006 - 09:42 #23
Nu har jeg sat "autopostback=true" ved alle tekstboxe. Når jeg så retter i den under kørsel, og med cursoren trykker udenfor tekstboxen, så sker der et postback, og værdien bliver igen det oprindelige. HVordan hænger det sammen?
Avatar billede cogitans Nybegynder
10. april 2006 - 09:44 #24
Ahhh....min fejl. Det er jo i page_load, hvor jeg udfylder felterne. Jeg har løst det nu...
Avatar billede cogitans Nybegynder
19. august 2006 - 18:00 #25
.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester