Avatar billede mema Nybegynder
12. juli 2006 - 09:21 Der er 24 kommentarer og
1 løsning

Slette en række i en Access database

Hej,
Ved min datagrid, der er tilkoblet en Access database har jeg sat en ButtonLink (Slet) som skulle slette en bestemt række i databasen, men min kode virker desværre ikke. Jeg bruger ASP.NET 1.1 og VS 2003. Her er aspx og aspx.cs filerne:
----------------
aspx:
----
<%@ Page language="c#" Codebehind="Mult_Oversigt.aspx.cs" AutoEventWireup="false" Inherits="EIS_test.Mult_Oversigt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>Master1</title>
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
<LINK href="style.css" type="text/css" rel="stylesheet">
</HEAD>
<body MS_POSITIONING="Flowlayout" bgColor="#6a828b">
<form id="Form1" method="post" runat="server">
<asp:datagrid id="grid" runat="server" CellPadding="3" PageSize="5" BorderColor="#CCCCFF" HorizontalAlign="Center"
AllowPaging="True" AutoGenerateColumns="False" Width="720px" Font-Names="Verdana" Font-Size="X-Small"
BackColor="White" DataKeyField="ID">
<AlternatingItemStyle BackColor="#E0E0E0"></AlternatingItemStyle>
<HeaderStyle BackColor="#AACCCC"></HeaderStyle>
<Columns>
<asp:BoundColumn DataField="ID" HeaderText="ID">
<HeaderStyle HorizontalAlign="Center" Width="70px"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="Navn" HeaderText="Navn">
<HeaderStyle HorizontalAlign="Center" Width="250px"></HeaderStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="Beskriv" HeaderText="Beskrivelse">
<HeaderStyle HorizontalAlign="Center" Width="250px"></HeaderStyle>
</asp:BoundColumn>
<asp:HyperLinkColumn Text="Detaljer" DataNavigateUrlField="ID" DataNavigateUrlFormatString="Multi_Details.aspx?ID={0}">
<HeaderStyle Width="100px"></HeaderStyle>
<ItemStyle ForeColor="#666666"></ItemStyle>
</asp:HyperLinkColumn>
<asp:ButtonColumn Text="Slet" CommandName="Delete">
<HeaderStyle Width="50px"></HeaderStyle>
</asp:ButtonColumn>
</Columns>
<PagerStyle BackColor="#AACCCC" Mode="NumericPages"></PagerStyle>
</asp:datagrid></form>
<TABLE id="Table1" cellSpacing="0" cellPadding="0" width="340" align="center" border="0">
</TABLE>
</body>
</HTML>
--------
aspx.cs:
----
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Data.OleDb;

namespace EIS_test
{
public class Mult_Oversigt : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid grid;
DataSet oDS = new DataSet();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}
}
private void BindGrid()
{
grid.DataSource = GetData();         
grid.DataBind();
}
private DataTable GetData()
{
string strConn, strCmd;
strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
strCmd = "SELECT ID, Navn, Beskriv, File1, File2, File3 FROM eis ORDER BY ID DESC";
OleDbDataAdapter oCMD = new OleDbDataAdapter(strCmd, strConn);
DataSet oDS = new DataSet();
oCMD.Fill(oDS, "eis");
DataTable dt = oDS.Tables["eis"];
return dt;
}

private void DeleteRow(object source, DataGridCommandEventArgs e)
{
DataRow[] objRows;
DataSet ds = new DataSet();
string strSelect;
strSelect = "ID='" + Convert.ToString(grid.DataKeys[e.Item.ItemIndex]) + "'";
ds = GetDataset();
objRows = ds.Tables["eis"].Select(strSelect);
objRows[0].Delete();
ds.Tables["eis"].AcceptChanges();
grid.EditItemIndex = -1;
BindGrid();
}
private DataSet GetDataset() 

DataSet ds = new DataSet();
OleDbDataAdapter objAdapter = new OleDbDataAdapter();
objAdapter.Fill(ds, "eis"); 
return ds; 
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
private void InitializeComponent()

this.grid.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.grid_PageIndexChanged);
this.grid.DeleteCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DeleteRow);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void grid_PageIndexChanged(object sender, DataGridPageChangedEventArgs e)
{
grid.CurrentPageIndex = e.NewPageIndex;
BindGrid();
}
}
}
Avatar billede agertoft Nybegynder
12. juli 2006 - 09:48 #1
Det du gør der er at slette rækken i selve det dataset, du bruger. Du skal slette rækken i din database. Det gør du ved at fyre en ExecuteNonQuery af hvor der står noget sql i retning af "DELETE FROM minTabel WHERE id = 3" fx... Her er et eksempel på, hvordan det kunne gøres:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e_
As System.EventArgs) Handles Button1.Click
myConnection = New SqlConnection("server=localhost;uid=sa;pwd=;database=pubs")
myConnection.Open()
myCommand = New SqlCommand("DELETE FROM minTabel WHERE id = 3",_
myConnection)
Dim nrRowsAffected as int32 =myCommand.ExecuteNonQuery()
myConnection.Close()

Efter at have kørt koden igennem kalder du GetData() igen..
Avatar billede snepnet Nybegynder
12. juli 2006 - 09:48 #2
Du skal sørge for at kalde update på din adapter (med dit dataset) - AcceptChanges nulstiller status på rækkerne.
Mvh
Avatar billede agertoft Nybegynder
12. juli 2006 - 09:51 #3
Du skal selvfølgelig bruge OleDb til at lave din connection. Du kan kigge på dette eksempel og få inspiration ;-)

http://www.easerve.com/developer/tutorials/asp-net-tutorials-delete-records-access-database.aspx
Avatar billede snepnet Nybegynder
12. juli 2006 - 09:52 #4
Ikke forstået på den måde, at du bliver nødt til at bruge en adapter ... Du skal jo sådan set bare bruge id'et som du allerede har fat i, hvis du vil slette i rækken.
Mvh
Avatar billede snepnet Nybegynder
12. juli 2006 - 09:52 #5
Hov ... nu krydser det jo helt vildt :o)
/im out
Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 10:41 #6
Jeg ved ikke hvordan skal kalde update på min adapter ved at bruge id'et?
Avatar billede mema Nybegynder
12. juli 2006 - 11:12 #7
Jeg bruger ButtonColumn i min datagrid for at slette. Jeg ved ikke hvordan man sætter en almindelige button i datagriden. Eller har jeg lavet følgende kode, men det virker deværre ikke. Faktisk har jeg slettet alt fra min tabel efter at have trykket på "Slet"!
Her er min metode (som sletter det hele og ikke kun en række):
private void grid_Delete(object source, DataGridCommandEventArgs e)
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
OleDbCommand minCmd = new OleDbCommand("Delete * FROM eis WHERE ID='" + ID + "'", conn);
minCmd.ExecuteNonQuery();
conn.Close();
GetData();
}
Avatar billede snepnet Nybegynder
12. juli 2006 - 11:12 #8
Med den model du bruger kan du bare slette den direkte med et connectionobjekt og et kommandoobjekt (hvor du så angiver den relevante sql), og så lave en
ditKommandoObjekt.ExecuteNonQuery();
Din BindGrid - metode vil jo hente det der aktuelt ligger i databasen, og sikre databinding mod det.
Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 11:43 #9
Skal jeg bruge min DeleteRow metode? og i dette tilfælde er spørgsmålet: hvordan skal den relevante sql ser ud?
Avatar billede snepnet Nybegynder
12. juli 2006 - 12:04 #10
Lidt trist at du har slettet alle dine rækker, men jeg kan heller ikke rigtig se hvor du har ID fra i den kode du viste her 12/07-2006 11:12:06
Men hvis du kan få fat i den rigtige id i den metode (som du gjorde i den første kode du viste) - så skulle du kunne bruge den sql du allerede har.
Det er dog en anbefaling at arbejde med parametre.
Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 12:37 #11
ID'et er jo Autonummerering i Access databasen og den hedder "ID". For at undgå forvirring (hos mig) ville jeg gerne beskrive hvad jeg tror du mener:

1- Jeg skal bruge disse 2 metoder:
private void DeleteRow(object source, DataGridCommandEventArgs e)
{
DataRow[] objRows;
DataSet ds = new DataSet();
string strSelect;
strSelect = "ID='" + Convert.ToString(grid.DataKeys[e.Item.ItemIndex]) + "'";
ds = GetDataset();
objRows = ds.Tables["eis"].Select(strSelect);
objRows[0].Delete();
ds.Tables["eis"].AcceptChanges();
grid.EditItemIndex = -1;
BindGrid();
}
private DataSet GetDataset()
{
DataSet ds = new DataSet();
OleDbDataAdapter objAdapter = new OleDbDataAdapter();
objAdapter.Fill(ds, "eis");
return ds;
}

2- Jeg skal skrive en connection og en delete-command (skal indrømme, at jeg ikke ved hvordan) og en ExecuteNonQuery() i en af disse 2 metoder og så kører det?
Mvh
Avatar billede snepnet Nybegynder
12. juli 2006 - 12:48 #12
Ja - den metode du sendte før:

private void grid_Delete(object source, DataGridCommandEventArgs e)
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
OleDbCommand minCmd = new OleDbCommand("Delete * FROM eis WHERE ID='" + ID + "'", conn);
minCmd.ExecuteNonQuery();
conn.Close();
GetData();
}

Der eksekverer du en sql med ExecuteNonQuery - og du gør du udfra en kommando du har skrevet.

Men... Hvis den skal gå godt - skal du have sat det rigtig id i variablen ID - og det kan jeg ikke se hvordan du gør (du postede selv noget kode til det tidligere).

Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 12:59 #13
Er det måske denne her?

"ID='" + Convert.ToString(grid.DataKeys[e.Item.ItemIndex]) + "'"
Avatar billede snepnet Nybegynder
12. juli 2006 - 13:11 #14
jeps
Avatar billede mema Nybegynder
12. juli 2006 - 13:25 #15
Nu har jeg ændret metoden til:
private void grid_DeleteCommand(object source, DataGridCommandEventArgs e)
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
OleDbCommand minCmd = new OleDbCommand("Delete * FROM eis WHERE" +
"ID='" + Convert.ToString(grid.DataKeys[e.Item.ItemIndex]) + "'");
minCmd.ExecuteNonQuery();
conn.Close();
GetData();
}

Men jeg får følgende fejl i browseren, når jeg klikker på "Slet":

Exception Details: System.InvalidOperationException: ExecuteNonQuery: Connection property has not been initialized.
Source Error:
Line 60: OleDbCommand minCmd = new OleDbCommand("Delete * FROM eis WHERE" +
Line 61: "ID='" + Convert.ToString(grid.DataKeys[e.Item.ItemIndex]) + "'");
Line 62: minCmd.ExecuteNonQuery();
Line 63: conn.Close();
Line 64: GetData();
Avatar billede mema Nybegynder
12. juli 2006 - 13:35 #16
Jeg havde glemt ", conn" i min minCmd. Nu ser min kode sådan ud:
private void grid_DeleteCommand(object source, DataGridCommandEventArgs e)
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
OleDbConnection conn = new OleDbConnection(strConn);
OleDbCommand minCmd = new OleDbCommand("Delete * FROM eis WHERE" +
"ID='" + Convert.ToString(grid.DataKeys[e.Item.ItemIndex]) + "'", conn);
conn.Open();
minCmd.ExecuteNonQuery();
conn.Close();
GetData();
}

Men nu får jeg følgende fejl i browseren:

Exception Details: System.Data.OleDb.OleDbException: Der er en syntaksfejl i FROM-delsætningen.
Source Error:
Line 61: "ID='" + Convert.ToString(grid.DataKeys[e.Item.ItemIndex]) + "'", conn);
Line 62: conn.Open();
Line 63: minCmd.ExecuteNonQuery();
Line 64: conn.Close();
Line 65: GetData();
Avatar billede snepnet Nybegynder
12. juli 2006 - 13:53 #17
Noget i denne stil kan du måske bruge:

// får fat i dit id
int id = int.Parse(Convert.ToString(grid.DataKeys[e.Item.ItemIndex]);
// og generér kommando
string command = String.Format("delete from eis where id='{0}'", id);

string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
OleDbConnection conn = new OleDbConnection(strConn);
OleDbCommand minCmd = new OleDbCommand(command, conn);
conn.Open();
minCmd.ExecuteNonQuery();
conn.Close();
GetData();

Du kan jo lige se om du kan få det til at funge - men som sagt... parametre er at foretrække (kan vi lige tage senere).

Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 14:00 #18
Har lavet om. Men nu får jeg denne fejl:

Exception Details: System.Data.OleDb.OleDbException: Datatyperne stemmer ikke overens i kriterieudtrykket.
Source Error:
Line 77: OleDbCommand minCmd = new OleDbCommand(command, conn);
Line 78: conn.Open();
Line 79: minCmd.ExecuteNonQuery();
Line 80: conn.Close();
Line 81: GetData();

Source File: c:\aspdotnet\webapps\eis-test\mult_oversigt.aspx.cs    Line: 79

Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 14:06 #19
Hvis det her ikke virker og/eller du har lyst, ville jeg gerne se hvordan kan man løse denne her med parametre.

Mvh
Avatar billede snepnet Nybegynder
12. juli 2006 - 14:24 #20
Hov - undskyld... Det var fordi du selv havde ping'er om:
Den skal være sådan her:
string command = String.Format("delete from eis where id={0}", id);

Med parametre kunne det se sådan ud:
OleDbCommand command = new OleDbCommand("delete from eis where id=@id", conn);
OleDbParameter parameter = new OleDbParameter("@id", OleDbType.Integer);
parameter.Value = id; // altså integerid'et fra før
command.Parameters.Add(parameter);

Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 14:51 #21
Hej,
Jeg har lavet om, men ved at trykke på slet har jeg slettet alle række, som jeg havde tilføjet. Koden nu:

private void grid_DeleteCommand(object source, DataGridCommandEventArgs e)
{
// får fat i dit id
int id = int.Parse(Convert.ToString(grid.DataKeys[e.Item.ItemIndex]));
// og generér kommando
string command = String.Format("delete from eis where id={0}", id);
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
OleDbConnection conn = new OleDbConnection(strConn);
OleDbCommand minCmd = new OleDbCommand(command, conn);
conn.Open();
minCmd.ExecuteNonQuery();
conn.Close();
GetData();
}
Avatar billede mema Nybegynder
12. juli 2006 - 15:03 #22
Nu heldigvis virker det med paramtre. Men der er en bugs og det er at siden bliver ikke opdateret efter sletning af en række.
Sådan ser koden ud:
private void grid_DeleteCommand(object source, DataGridCommandEventArgs e)
{
// får fat i dit id
int id = int.Parse(Convert.ToString(grid.DataKeys[e.Item.ItemIndex]));
// og generér kommando
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + MapPath("Data/EIS.mdb");
OleDbConnection conn = new OleDbConnection(strConn);
OleDbCommand command = new OleDbCommand("delete from eis where id=@id", conn);
OleDbParameter parameter = new OleDbParameter("@id", OleDbType.Integer);
parameter.Value = id; // altså integerid'et fra før
command.Parameters.Add(parameter);
conn.Open();
command.ExecuteNonQuery();
conn.Close();
GetData();
}

Smid venligst et svar :-)
Avatar billede snepnet Nybegynder
12. juli 2006 - 15:13 #23
Hvis din GetData() ser ud som det du postede tidligere, så er det klart nok. Kald BindGrid() istedet - Som du har vist den henter den data og udfører databinding.
Mvh
Avatar billede mema Nybegynder
12. juli 2006 - 15:28 #24
Tusind tak.
Mvh
Avatar billede snepnet Nybegynder
14. juli 2006 - 12:06 #25
Det var så lidt :o)
Mvh
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