Error while deleting record from database - sql

I need some help with delete record from database.
I am trying to delete a record from a table in my SQL Server database.
Am I missing something?
Private Sub cmdDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDelete.Click
_DataSet.Tables(0).Rows(CInt(txtCurrent.Text) - 1).Delete()
' tho, it can remove the deleted rows
' we cannot call the DataSet.AcceptChanges method
' because the DataAdapter would not recognize the delete row
' by the time DataAdapter.Update(DataSet) is called.
EnableNavigation()
cmdSave.Enabled = True ' let user update the underlying database
' after deleting the current record, the current record still points to the
' deleted record (though it cannot be updated).
' The user must MoveNext/Back to view other records.
End Sub

DataRow.Delete does not delete this row from database. It marks the DataRow's RowState as deleted. This will be checked from a DataAdapter if you call Update. If it's state is Deleted it will look for its according DeleteCommand which you have to provide.
So you need to provide a DeleteCommand for your DataAdapter which is the sql to delete the row from the database.

You want to Delete it
_DataSet.Tables(0).Rows(CInt(txtCurrent.Text) - 1).Delete()
Dim adapter As New SqlDataAdapter
Dim cmdBuilder As New SqlCommandBuilder(adapter)
Dim DutyDetails As String = "SELECT * from MyTable"
adapter.SelectCommand = New SqlCommand(DutyDetails, SQLConn)
adapter.UpdateCommand = cmdBuilder.GetUpdateCommand
adapter.DeleteCommand = cmdBuilder.GetDeleteCommand
Dim cb As SqlCommandBuilder = New SqlCommandBuilder(adapter)
adapter.Update(_DataSet.Tables("0"))
Source: Deleting a record from dataset and sql server

You refer to the table as _DataSet.Tables(0), then refer to it later as _DataSet.Tables("0") I bet one of the two is incorrect.

Related

Datagridview - Oracle Update error "Dynamic SQL generation failed."

I'm using Datagridview to show me joined records from 2 tables. Data that is showing is from one of the tables + data that are in joined table (Table3). SQL query returns results in Datagridview (works fine in Oracle too), but update fails with "Dynamic SQL generation failed. Either no base tables were found or more than one base table was found". Here is my table design:
Table1:
ID_TABLE1
ITEM_NAME
ITEM_DESCRIPTION
Table3: (this is a joined view for Table1 and Table2)
ID_TABLE3
ID_TABLE1_FK
ID_TABLE3_FK
VALIDITY
DATE_CONNECTION
My code (exactly as Oracle recommends):
Public Class Form2
Private da As OracleDataAdapter
Private cb As OracleCommandBuilder
Private ds As DataSet
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Saving.Enabled = False 'this deals with error with updating (from Oracle site)
Dim SQL As String = "SELECT ID_TABLE1, ID_TABLE3, SERIAL_NO, ITEM_NAME, ITEM_DESCRIPTION, VALIDITY, DATE_CONNECTION from TABLE1, TABLE2 WHERE TABLE3.ID_TABLE1_FK=" & Form1.DataGridView1.CurrentRow.Cells(0).Value.ToString
Try
Oracleconn() 'connection to my DB
Dim cmd = New OracleCommand(SQL, Oracleconn)
cmd.CommandType = CommandType.Text
da = New OracleDataAdapter(cmd)
cb = New OracleCommandBuilder(da)
ds = New DataSet()
da.Fill(ds)
My_DGV.DataSource = ds.Tables(0)
Saving.Enabled = True
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
'No closing of connection here because of working with Dataset (Oracle suggestion)
End Try
End Sub
Private Sub Saving
da.Update(ds.Tables(0))
Saving.Enabled = True
End Sub
End Class
So, Is my SQL query wrong or what ? Any help would be much appreciated !
P.S.: In actual case only column "VALIDITY" from Table3 will be allowed to change for users, so I need to update only that field.
This is too complicated for me, looks like Oracle-provided suggestion for working with Datasets just isn't easy when you want to perform Update on join table records. So I tried a different approach and It worked for me. Since what I need is to update only 1 column from SQL query which returns to Datagridview I did this :
For Each row As DataGridViewRow In My_.Rows
cmd.Parameters.Add(New OracleParameter("validity", row.Cells(6).Value))
cmd.CommandText = "UPDATE TABLE3 SET VALIDITY= : validity WHERE ID_TABLE1_FK='" & row.Cells(1).Value & "'"
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
Next
If anyone knows the answer to my original question - so how to do same with just da.Update(ds.Tables(0)), then please let me know. I reckon that SQL query needs to be properly changed, using JOIN method.

SqlDataAdapter.Fill(DataGridView.DataSource) duplicates all rows

Simple question:
When I call SqlDataAdapter.Fill(DataGridView.DataSource) the second time after initially creating first Data it does not update the contained rows. It simply adds all rows returned by the select command to my DataGridView.
If I call it a third, fourth (so on) it will also just add the returned rows.
Am I understanding the .Fill(DataTable) function wrong? How do I update the already existing DataTable correctly? Which line of code is responsible for that?
Turns out it has to be a code problem;
DataGridView1.AutoGenerateColumns = False
Dim sql = "select * from myTable"
oDtSource = New DataTable
oAdapter = New SqlDataAdapter
oCon = sqlCon("serverName\Instance", "myDataBase") ' Returns a SqlConnection
oCmd = New SqlCommand(sql, oCon)
oCon.Open()
oDtSource.Clear()
oAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
oAdapter.SelectCommand = oCmd
oAdapter.Fill(oDtSource)
DataGridView1.DataSource = oDtSource
For refreshing I use oAdapter.Fill(oDtSource)
The PrimaryKey is set in the database
From MSDN:
You can use the Fill method multiple times on the same DataTable. If a
primary key exists, incoming rows are merged with matching rows that
already exist. If no primary key exists, incoming rows are appended to
the DataTable.
So either define a primary key or clear the table first.
Dim table = CType(DataGridView.DataSource, DataTable)
table.Clear()
' fill ...
To define primary key(s) manually read this. To let it create automatically if they are defined in the database you need to set the MissingSchemaAction to AddWithKey:
' ...
dataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
' fill ...
The edit code doesnt show the PrimaryKey being defined for the DataTable. This will configure the DataAdapter to perform updates and enabled refreshing the DataTable. The code uses MySQL but the Provider objects all work the same in this regard:
' persistant form level vars
Private daSample As MySqlDataAdapter
Private dtSample As DataTable
...
Elsewhere:
' there are caveats with WHERE clauses
Dim sql = "SELECT Id, Name, Country, Animal FROM SAMPLE WHERE Color = 'onyx'"
' using the ctor overload, no need for a DbCommand or Connection object
daSample = New MySqlDataAdapter(sql, MySQLConnStr)
' initialize the CommandBuilder, get other commands
Dim cbSample = New MySqlCommandBuilder(daSample)
daSample.UpdateCommand = cbSample.GetUpdateCommand
daSample.InsertCommand = cbSample.GetInsertCommand
daSample.DeleteCommand = cbSample.GetDeleteCommand
dtSample = New DataTable()
daSample.FillSchema(dtSample, SchemaType.Source)
dtSample.PrimaryKey = New DataColumn() {dtSample.Columns("id")}
daSample.Fill(dtSample)
dgv1.DataSource = dtSample
To pick up changes made to the db from other client apps:
daSample.Fill(dtSample)
Initial display:
After I change a row to "onyx" from a UI browser and Update the changed row shows up:
WHERE clauses can be a bit of an issue. Since it restricts the subset of data pulled back, Update is only going to compare rows in the new result set. So, if I change an onlyx row to "blue" it wont be removed.
One solution is to use .DefaultView.RowFilter on the table, but that can slow things down since it requires returning all rows to the client to be filtered there. Its not perfect.

Adding new records to a DataTable

I am having trouble inserting new rows into a database with multiple tables. Currently I have my database connected to my Visual Basic project. What I have so far is this:
Imports System.Data.SqlClient
Public Class MainForm
Private m_cn As New SqlConnection()
Private m_DA As SqlDataAdapter
Private m_CB As SqlCommandBuilder
Private m_DataTable As New DataTable
Private m_IntRowPosition As Integer = 0
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles Me.Load
m_cn.ConnectionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename = C:\Users\pattanasio\Desktop\Visual Basic Projects\DPG Project Hours Database\Mestek Database.mdf;Integrated Security=True;Connect Timeout=30"
m_cn.Open()
m_DA = New SqlDataAdapter("SELECT * FROM Employee_Table", m_cn)
m_CB = New SqlCommandBuilder(m_DA)
m_DA.Fill(m_DataTable)
End Sub
Private Sub btnInsertIntoDatabase_Click(sender As Object, e As EventArgs) Handles btnInsertIntoDatabase.Click
Dim drNewRow As DataRow = m_DataTable.NewRow()
For m_IntRowPosition = 0 To lstScannedNames.Items.Count()
If m_DataTable.Rows.Count = 0 Then
drNewRow("emp_id") = m_IntRowPosition + 1
drNewRow("emp_name") = lstScannedNames.Items.Item(m_IntRowPosition)
m_DataTable.Rows.Add(drNewRow)
m_DA.Update(m_DataTable)
m_IntRowPosition = m_DataTable.Rows.Count - 1
End If
Next m_IntRowPosition
End Sub
End Class
When I run my program and click that button, I get an error on the drNewRow("emp_name") line saying that the column emp_name does not belong to the table. The full error says it is An unhandled exception of type 'System.ArgumentException' occurred in System.Data.dll I'm also wondering why the error isn't thrown on the line before where I reference the emp_id column. My guess is that I'm getting this error because my DataTable object does not know which data table in the database to reference. Also, it may be worth noting that emp_id is the primary key for 1 of my 5 tables and is also the foreign key in 3 other tables. I feel like I'm close but I've been stuck for a few hours. Sorry if my terminology isn't spot on, I'm quite new at this.
My Database looks like this.
Here is the pastebin link to my code: http://pastebin.com/UiYXEZMG
Ok, it is definitely worth noting that when I look through the Autos window to see the table my drNewRow is inserting into, and then use the text visualizer, it shows the 4 columns I originally had. 1 column for emp_id and 3 other columns for first, middle, and last name. However, in the database designer, I deleted 2 of the name columns and renamed the remaining one to emp_name, without touching emp_id. This is definitely the cause of my problem but I'm not sure how to fix it. So in the database designer .xsd file it shows my table how I would like it to be. But in the Autos window it shows that it is using the old table. Also if I wanted to work with a different table, would I just have to SELECT a different table in my SqlDataAdapter?

Executing delete command on MS-Access through VB.NET does not delete the records

Just trying to delete all rows of an Access table:
Private Sub btnImport_Click(sender As Object, e As EventArgs) Handles btnImport.Click
'Clear old records from extract table
Dim sqlConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\CLI_CRVM.accdb")
Dim cmd As New System.Data.OleDb.OleDbCommand()
Dim intRC As Integer
cmd.CommandType = System.Data.CommandType.Text
cmd.CommandText = "DELETE * FROM [extract] ;"
cmd.Connection = sqlConnection
sqlConnection.Open()
intRC = cmd.ExecuteNonQuery()
sqlConnection.Close()
MsgBox(intRC)
End Sub
I do not get any errors but it doesn't delete the rows either. There are currently 10 rows in the table and the MsgBox shows 10 each time the button is clicked and there are still 10 rows in the table afterwards.
What am I missing?
Try without the asterisk:
DELETE FROM [extract];
You don't generally supply any columns in a DELETE. You only supply columns that you want to match a row against .. via a WHERE clause afterwards.
There are certain dialects of SQL that let you specify thresholds on what you delete in that part of the query - however, I don't believe Access' dialect does (I could be wrong).

data grid view update ,Edit and delete in vb.net windows form that using multiple table to populate datagridview

I am new to windows Forms applications...
I am working in VB.NET windows forms and dealing with DataGridView...
I have populated that DataGridView from two Table
Please tell me How to Add , Delete and Edit/Update the records of the DATAGridview back to the DataBase.
I am using SQLSERVER 2008 DataBase
I have two tables 1->CompanyMaster_tbl in this having Two fields . Cid and CompanyName,
Cid is the primary key of this table
2->DepartmentMaster_tbl in this having 4 fields. dtid,dtname,dtphon,dtmail,Cid.
dtid is the primary key,and Cid is the foreign key..
My data gridview look like this:
Dim adapter As SqlDataAdapter
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'NOTE: I removed the Using statements to ease your tests/understanding, but you shouldn't let the connections opened (or, at least, set connection-release part somewhere)
Dim con As SqlConnection = New SqlConnection() 'SET THE CONNECTION STRING
con.Open()
adapter = New SqlDataAdapter("select c.CompanyName,d.dtName,d.dtPhone,d.dtEmail from CompanyMaster_tbl c join DepartmentMaster_tbl d on c.Cid=d.cId", con)
Dim dt As DataTable = New DataTable()
adapter.Fill(dt) 'Filling dt with the information from the DB
gv.DataSource = dt 'Populating gv with the values in dt
End Sub
in update button i wrote code like this:
Dim dt1 As DataTable = DirectCast(gv.DataSource, DataTable)
adapter.Update(dt1)
but after editing anything in gridview,,i click the update button,,but i am getting error in this row
da.Update(dt1)
Error:
Update requires a valid UpdateCommand when passed DataRow collection with modified rows.
Thanks in advance
If you want to keep some synchronisation between the DataGridView and the DB, you shouldn't add columns/rows manually, but rely on the DataSource property. Sample code adapted to your case:
Using con As SqlConnection = New SqlConnection() 'You have to set the CONNECTION STRING
con.Open()
Using adapter As SqlDataAdapter = New SqlDataAdapter("select c.CompanyName,d.dtName,d.dtPhone,d.dtEmail from CompanyMaster_tbl c join DepartmentMaster_tbl d on c.Cid=d.cId", con)
Dim dt As DataTable = New DataTable()
adapter.Fill(dt) 'Filling dt with the information from the DB
gv.DataSource = dt 'Populating gv with the values in dt
End Using
End Using
The code above extracts all the information you want from the DB, puts it into a DataTable (dt) and then feeds it to the DataGridView as DataSource. gv has now all the values from dt; also any change in dt is reflected in gv and vice versa (this coupling is almost perfect, at least, when updating values; there might be some problems while deleting rows/columns or changing their basic configuration). You might even keep adapter as a global variable (outside the Using statement) and rely on it to update the DB regularly (via adapter.Update(dt), for example).
Quite a few alternatives; but, in any case, relying on a DataSource is certainly better under your conditions.