Unable to delete from database - sql-server

Unable to delete data from database in vb.net using SQL Server.
Here is my code for deletion, can you tell me where I have gone wrong?
Name of the table is OneToOne:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
cn.Open()
With cmd
.Connection = cn
.CommandText = " DELETE * FROM OneToOne WHERE SrNo = " & DataGridView1.SelectedRows(0).Cells(0).Value
i = cmd.ExecuteNonQuery
End With
If (i > 0) Then
MsgBox("Conversation Deleted")
End If
cn.Close()
showdata()
End Sub

To delete all rows at once, you can iterate through the selected rows and build a comma-separated string of the Cell(0) values.
Then instead of using WHERE srNo = , use WHERE srNo IN ({your string})
At least, this is the way to do it following your current approach. A better way would be to pass a table-valued parameter to a stored procedure, but that's a broad subject that you would need to research.
And, as with most programming questions, there are multiple other ways this can be done.

on_button_click
s = "DELETE FROM OneToOne WHERE SrNo IN(val1,val2.....valn)"
cn.Open()
cmd = New SqlCommand(s, cn)
i = cmd.ExecuteNonQuery()
If i > 0 Then
MsgBox("yup")
End If
cn.Close()
val1,val2.. are your SrNo values. It's on you how you retrieve/provide SrNo values

Related

Inserting data into database with autonumber in VB.net

I'm trying to insert data into a database with an autonumber in MS Access as primary key. I get an error saying "Number of query values and destination fields are not the same. The data types in MS Access are Autonumber (I didn't include it in the INSERT statement), String (#OrderNo), String (#Product), Number (#Qty), and Date (#TDate). Here's the image:
Here's my code:
For Each row As DataGridViewRow In DataGridView1.Rows
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Daily Inventory.accdb;"
Using conn As New OleDbConnection(connString)
Using cmd As New OleDbCommand("Insert into Table1 Values(#OrderNo, #Product, #Qty, #TDate)", conn)
cmd.Parameters.AddWithValue("#OrderNo", TxtOrder.Text.ToString)
cmd.Parameters.AddWithValue("#Product", row.Cells("Product").Value)
cmd.Parameters.AddWithValue("#Qty", row.Cells("Qty").Value)
cmd.Parameters.AddWithValue("#TDate", Date.Now.ToString("MM/dd/yyyy"))
If conn.State = ConnectionState.Open Then
conn.Close()
End If
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
End Using
End Using
Next
You need to change your sql to "Insert into Table1 (OrderNo,Product,Qty,TDate) Values(#OrderNo, #Product, #Qty, #TDate)".
The following code works for me.
DataGridView1.AllowUserToAddRows = False
For Each row As DataGridViewRow In DataGridView1.Rows
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=...;"
Using conn As New OleDbConnection(connString)
Using cmd As New OleDbCommand("Insert into Table1 (OrderNo,Product,Qty,TDate) Values(#OrderNo, #Product, #Qty, #TDate)", conn)
cmd.Parameters.AddWithValue("#OrderNo", TxtOrder.Text.ToString)
cmd.Parameters.AddWithValue("#Product", row.Cells("Product").Value)
cmd.Parameters.AddWithValue("#Qty", row.Cells("Qty").Value)
cmd.Parameters.AddWithValue("#TDate", Date.Now.ToString("MM/dd/yyyy"))
If conn.State = ConnectionState.Open Then
conn.Close()
End If
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
End Using
End Using
Next
Well, I think we dealing with a bit of a chicken and a egg problem here?
I mean, how did the grid get created?
How and where did you setup the columns in the grid?
lets drop a data grid view into a form. Drop in a button.
We have this code to load up the grid:
Private Sub HotelGridEdit_Load(sender As Object, e As EventArgs) Handles Me.Load
LoadGrid()
End Sub
Sub LoadGrid()
Using conn As New OleDbConnection(My.Settings.AccessDB)
Dim strSQL As String =
"SELECT ID, FirstName, LastName, City, HotelName, Description, Active FROM tblHotelsA
ORDER BY HotelName"
Using cmdSQL As New OleDbCommand(strSQL, conn)
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
DataGridView1.DataSource = rstData
End Using
End Using
End Sub
So, now we have this:
Now, in a above, I can cursor around - make any edits I want.
I can also type in on the bottom blank row to add new rows.
I can click on the left side recordselector, and hit delete key.
Now, to save my edits, save my addtitions, and save my deletes?
I have the one button at the top, and this code works to do all updates, all addtitions, and all deletes.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' save all edits, and new rows, and deletes
Using conn As New OleDbConnection(My.Settings.AccessDB)
Dim strSQL As String =
"SELECT ID, FirstName, LastName, City, HotelName, Description, Active FROM tblHotelsA"
Using cmdSQL As New OleDbCommand(strSQL, conn)
conn.Open()
Dim da As New OleDbDataAdapter(cmdSQL)
Dim daC As New OleDbCommandBuilder(da)
da.Update(DataGridView1.DataSource)
End Using
End Using
End Sub
So, not a lot of code.
In fact, often using a data table is a lot less work, since you don't have to mess with all those parameters anyway - even if your data grid was somehow not feed from the database. But, if you feeding the "grid" from the database, then really, you can just add rows - and then write some code to send the changes back to the database with the above code. And if you want to start out with a blank grid - not show previous rows, then just add to your sql like this:
SELECT * from tblHotels WHERE ID = 0 Order by Hotelname
Use above to create a data table without any rows but STILL bind that to the grid, and thus once again, to add, or delete rows, you just edit and add them, and again the SAME code I had above will work to save edits, deletes and additions.

How to display all elements in a column using cmd.ExecuteReader from mdf data file in Visual Basic

Here's my .mdf database file that has 5 columns
I want to add each of those values from my Id column in a list
Private Sub Read_Click(sender As Object, e As EventArgs) Handles Read.Click
Try
If con.State = ConnectionState.Open Then
con.Close()
End If
con.Open()
cmd = con.CreateCommand()
cmd.CommandType = CommandType.Text
cmd.CommandText = "SELECT Id FROM tablekongbago"
cmd.ExecuteNonQuery()
Dim dr As SqlClient.SqlDataReader
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
While dr.Read
element = dr.GetInt32(0).ToString()
End While
Catch ex As Exception
End Try
MessageBox.Show(element)
End Sub
The problem is that I can only retrieve the last row of my Id column and not all of the values from my Id column using
element = dr.GetInt32(0).ToString()
If I try to iterate and turn it into
dr.GetInt32(1).ToString()
it displays nothing.
I want to create a collection of Id's to a List(Of Integer) I know how to create a list and a for loop but I don't know how can I retrieve all of my Id's from my Id column, what kind of code should I use if "dr.GetInt32(0)" is only for the last row of the Id column?, is there a way I can loop starting from the very first top row up to the last row of my Id column? I want something like "list[0] - referring to the first row and list[2] - referring to the last row, so that I can add it my List(Of Integer).
I cringe whenever I see If con.State = ConnectionState.Open Then. Connections should be declared in the method where they are used. You should never have to question the ConnectionState.
You have executed your command twice. A Select in not a NonQuery. NoQuery is Insert, Update and Delete.
Your While loop keeps overwriting the element varaiable on each iteration so you only get the value in the last record.
Never write an empty Catch block. It will just swallow errors and you may get unexpected results with no clue why.
It is a good idea to separate you database code from you user interface code.
Create your connection and command with a Using...End Using block so you know they are properly disposed. Likewise with the reader. I like to do as little as possible with a reader because it requires and open connection and connections should be open for as short a time as possible.
Private ConStr As String = "Your connection string"
Private Sub Read_Click(sender As Object, e As EventArgs) Handles Read.Click
Dim dt As DataTable
Try
dt = GetIds()
Catch ex As Exception
MessageBox.Show(ex.Message)
Return
End Try
Dim ListOfIDs = (From row As DataRow In dt.AsEnumerable
Select CInt(row(0))).ToList
ListBox1.DataSource = ListOfIDs
End Sub
Private Function GetIds() As DataTable
Dim dt As New DataTable
Using con As New SqlConnection(ConStr),
cmd As New SqlCommand("SELECT Id FROM tablekongbago;", con)
con.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
You can simply create a List of Integer and add the ids to your collection during each call to dr.Read()
Dim ids = New List(Of Integer)()
While dr.Read()
ids.Add(dr.GetInt32(0))
End While
You code looks a bit messed up. This should work:
Note that a sql command object is VERY nice.
It has a reader built in - you don't need to define one
It has the command text - you don't need to define one
it has a connection object - again no need to create one (but you look to have one)
And using a dataTable is nice, since you can use for/each, or use the MyTable.Rows(row num) to get a row.
And a datatable is nice, since you don't need a loop to READ the data - use the built in datareader in sqlcommand object.
Using cmdSQL As New SqlCommand("Select Id FROM tblekingbago", con)
cmdSQL.Connection.Open()
Dim MyTable As New DataTable
MyTable.Load(cmdSQL.ExecuteReader)
' table is now loaded with all "ID"
' you can see/use/display/play/have fun with ID like this:
For Each OneRow As DataRow In MyTable.Rows
Debug.Print(OneRow("Id"))
Next
' display the 5th row (it is zero based)
Debug.Print(MyTable.Rows(4).Item("Id"))
End Using

SQL Server database population pre-existing Data Table and fields (FORM). NO database file

Here is my general understanding of database from what I read so far: Save / Update / Delete to pre-existing file made that binds to form thru SQL.
Here is what I am trying to do - I have a pre-made Data Table in Form with all columns defined. Once app is closed or certain functions ran, I need that data to be saved / updated in SQL (on local). Once app is open I need all that data to be preserved.
So far I have NOT found a single solution to it anywhere most refer to binding to an existing file. When I worked with Excel data transfer cells had to be defined and referenced in form for population.
My assumption is when a database from VB.NET is used, table with values can be created automatically saved/loaded/updated. However this is only my assumption since I never worked with SQL before. I am not sure if I need to manage an actual database file I created with all the values and then bind them to data table. For example DataTable cell XX to database column XX.
Here is what I done so far I have created database and added to my project. I tried few codes and I keep getting Dataset Empty even though there is Data in Table I tried to use DataTable as well but so far nothing has worked.
Please suggest on what I am doing wrong also additional information regards to databases will be great. As per previous I do know how binding works when actual file exist. But creating and managing is confusing to me since I keep thinking there should be a binding file.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "SELECT BN FROM DataTable" ' BN is my column name and DataTable is the name of my Table where data gets populated. This is also confusing to me How does it know which value is what? Is there are space/word/characters requirements?
' adapter.TableMappings.Add("DataTable", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds)
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
Code I use to Create /Save Database. As per previous all columns/formats are pre-made, loaded.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "Select BN FROM DataTable"
adapter.TableMappings.Add("BN", sql)
If DataTable.RowCount > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf DataTable.RowCount = 0 Then
MsgBox("Empty data")
End If
End Sub
Please see more info below:
Data Table columns/format are structured for visual representation.
When User start the App Database can be empty/Can contain Values.
When users Runs certain function Closes App values are save and only values.
If I would you an MS Access I would structure same table/values and cross reference it with form values. Form Values come from outside source and Format/Qty is always known.
Hope this helps to have a cleaner look at my issue. Perhaps SQL is not a right choice for me? Does SQL needs to be build before value manipulation.
UPDATE: I Got rid of the Invalid Object error. Table had to be created 1st as I originally thought. However, My DataSet always comes up as EMPTY when I try to save... Cells do contain BN data as" 1,2, ....) Even if I to remove "If" logic Save and Load table comes out as empty. Something does load because when I try to ADD BN it tells me binding bla bla bla(different issue)
CODE:
Private Sub SaveData()
Dim connetionString As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Dim sql As String = "SELECT BN FROM DataTable_d"
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet()
adapter.TableMappings.Add("BN", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
UPDATE: I got all the things working but I can't save multiple rows..... Could really use some help
In your SQL query remove WHERE DataTable ='. This statement is looking for a column name DataTable which I assume does not exist. The WHERE clause is used to help filter your query. You only use WHERE on column names in your table.
For instance:
SELECT BN FROM DataTable
will return all values from the BN column from DataTable.
Note that if you have multiple columns, the above query will still only return values from BN.
SELECT * FROM DataTable
will return every value in DataTable.
A helpful site to look at documentation for SQL is w3schools.
Let's start with just displaying some data. Add a DataGridView to a Form. You can call LoadData() from a button. I am not very sure of you connection string but give it a try.
Private dt As DataTable
Private sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Private Sub LoadData()
'***EDIT*** Add instantiation line
dt = New DataTable()
'The Using...End Using blocks will close and dispose your database objects
'even if there is an error
Using cn As New SqlConnection(sql)
'You can pass the command text and the connection directly to the constructor
'In the select statement use the actual names of the field and table as they appear in the database.
Using cmd As New SqlCommand("Select BN From [Insert the name of the table in the database]", cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
This is the simplest way I can think of to display data. We will proceed with changing the data once this works. If you get an error on cn.Open() We will have to work on the connection string.
****EDIT****
Private Sub TestConnection()
Dim sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Using cn As New SqlConnection(sql)
cn.Open()
End Using
End Sub

SQL Server query parameter for copy data table to another table form ListView VB.net

I'm using VB.net 2013 and SQL Server Express. I want to copy data from the table that appears in the listview to the temporary table. But I got an error:
Operator '&' is not defined for types 'String' and 'System.Windows.Forms.ListViewItem.ListViewSubItem'
What are the correct parameters?
My code looks like this
For Each itm As ListViewItem In ListViewMasterBiaya.CheckedItems
Dim SIMPAN As String = "INSERT INTO TempEntriBiaya WHERE NoKode='" & ListViewMasterBiaya.SelectedItems(0).SubItems(0) & "'"
CMD = New SqlCommand(SIMPAN, CONN)
CMD.ExecuteNonQuery()
Next
End Sub
I also include the image as below, when I check it, the data will also copy to the temporary table
Comments and explanation in-line. Following LarsTech comments.
Dim SIMPAN As String = "INSERT INTO TempEntriBiaya (Column1Name, Column2Name) Values (#Column1, #Column2);"
'The Using...End Using blocks ensure that your ADO objects are closed and
'disposed event if there is an error
Using cn As New SqlConnection("Your connection string")
'The command and parameters only need to be declared once
'outside the loop, only the value of the parameters change
Using cmd As New SqlCommand(SIMPAN, cn)
cmd.Parameters.Add("#Column1", SqlDbType.Int)
cmd.Parameters.Add("#Column2", SqlDbType.VarChar)
'Open the connection at the last possible moment
cn.Open()
For Each itm As ListViewItem In ListViewMasterBiaya.CheckedItems
cmd.Parameters("#Column1").Value = itm.SubItems(0).Text
cmd.Parameters("#Column2").Value = itm.SubItems(1).Text
cmd.ExecuteNonQuery()
Next
End Using
End Using
EDIT Use event ListView.ItemChecked
Private Sub ListViewMasterBiaya_ItemChecked(sender As Object, e As ItemCheckedEventArgs) Handles ListViewMasterBiaya.ItemChecked
'e.Item returns the ListViewItem that changed its check
If e.Item.Checked = True Then
Dim SIMPAN As String = "INSERT INTO TempEntriBiaya (Column1Name, Column2Name) Values (#Column1, #Column2);"
'The Using...End Using blocks ensure that your ADO objects are closed and
'disposed event if there is an error
Using cn As New SqlConnection("Your connection string")
Using cmd As New SqlCommand(SIMPAN, cn)
cmd.Parameters.Add("#Column1", SqlDbType.Int).Value = e.Item.SubItems(0)
cmd.Parameters.Add("#Column2", SqlDbType.VarChar).Value = e.Item.SubItems(1)
'Open the connection at the last possible moment
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End If
End Sub

Most efficient way to find a record in Access linked to SQL Server database

I have a multi user Access UI linked to a SQL Server database that is used to perform loan reviews for a mortgage company. Users are currently using the 'Find Record' function that already exists in Access and it takes a very long time to locate the record. While I do understand why it takes so long and what it theoretically needs to do, I can't figure out the best way to write code to do directly to the record needed. It needs to be a message box similar to the existing find record function, but that performs the most efficient way. I tried the following, which doesn't include a message box, and it doesn't work:
Private Sub txtFindLoan_AfterUpdate()
Dim sSQL As String
sSQL = "SELECT * FROM dbo_PreCloseAuditEnc WHERE LOAN_NUM = '" &
Me.txtFindLoan & "'"
Me.RecordSource = sSQL
Me.Requery
End Sub
Thanks in advance!
There is no bottleneck, except that you don't need a requery. And, of course, make sure you have an index on the LOAN_NUM field.
You could have an InputBox to pick up the loan number. The code could be called from a button:
Private Sub LoanButton_Click()
Dim sLoanNo As String
Dim sSQL As String
sLoanNo = InputBox("Loan Number:", "Select Loan Number")
If sLoanNo <> "" Then
' Input provided.
' Validate input.
' IsValidLoanNumber will be a function to do this. Must return True/False.
If IsValidLoanNumber(sLoanNo) Then
sSQL = "SELECT * FROM dbo_PreCloseAuditEnc WHERE LOAN_NUM = '" & sLoanNo & "'"
Me.RecordSource = sSQL
End If
End If
End Sub
You're probably off best using ADODB since you're only using external data, and binding the form directly to a filtered ADODB recordset.
As Sean Lange said, you should parameterize your query, and you can do that either using DAO or ADO, but not by modifying the Me.RecordSource property
Private Sub txtFindLoan_AfterUpdate()
Dim sSQL As String
'I'm assuming your table name in MS SQL is dbo.PreCloseAuditEnc
sSQL = "SELECT * FROM dbo.PreCloseAuditEnc WHERE LOAN_NUM = ?"
Dim adoConn As New ADODB.Connection
'Enter a valid OLEDB connection string here:
adoConn.Open "Provider=SQLNCLI11;Server=myServerAddress;Database=myDataBase;Trusted_Connection=yes;"
Dim cmd As New ADODB.Command
cmd.ActiveConnection = adoConn
cmd.CommandText = sSQL
cmd.Parameters.Append cmd.CreateParameter(Type:=adChar, Value:=Me.txtFindLoan)
Me.RecordSet = cmd.Execute
End Sub

Resources