SQL Error: "There are no rows at position 0" - sql

I am Trying to create a login form for my software and i keep getting this feedback as error; "There are no rows at postion 0".....This happens whenever i try to add a WHERE clause to my (SLELECT ProfileName, ProfilePassword from Profile) query (i.e 'sqlQuery' in code)......This is a snippet of my code
Public Sub sql_login(ByVal sqlQuery As String)
Try
'OPENING THE CONNECTION
con.Open()
'INITIALIZE YOUR COMMANDS
'IT HOLDS THE DATA TO BE EXECUTED
With cmd
'PASS ON THE VALUE OF CON TO THE MYSQL COMMANND WHICH IS THE CONNECTION
.Connection = con
'THE FUNCTION OF THIS IS TO RETURN THE TEXT REPRESENTED BY A COMMAND OBJECT
.CommandText = sqlQuery
End With
Dim dt = New DataTable
'FOR RETRIEVING AND FILLING DATA IN THE TABLE
Dim da = New SqlDataAdapter(sqlQuery, con)
'NEW TABLE IN THE DATATABLE
da.Fill(dt)
con.Close()
'SET THE TOTAL ROWS OF THE TABLE IN A VARIABLE[MAXROWS]
Dim maxrows As Integer = dt.Rows.Count
con.Close()
'preventing non empty values
If Loginform.UsernameTextBox.Text <> "" And Loginform.PasswordTextBox.Text <> "" Then
If dt IsNot Nothing Then
'CHECKING IF THE TOTAL ROWS OF THE TABLE ARE GREATER THAN 0
If maxrows > 0 Then
'THIS WILL BE NOTIFY YOU THAT WHO WOULD BE THE USER'S
MessageBox.Show("Welcome " & dt.Rows(1).Item(0) & "!" & ControlChars.NewLine & "You have sucessfully logged in.", "Login Confirmation")
'Tracing login time
Try
cmd.CommandType = System.Data.CommandType.Text
cmd.CommandText = "INSERT INTO ProfileDates (ProfileName, LoginDates, ProfileID) VALUES ('" & Loginform.UsernameTextBox.Text & "',GetDate(),( SELECT TOP 1 profileID FROM Profile where ProfileName = '" & Loginform.UsernameTextBox.Text & "') )"
cmd.Connection = con
con.Open()
cmd.ExecuteNonQuery()
con.Close()
Suppliers_Module.LogoutBtn.Enabled = True
Suppliers_Module.LoginButton.Enabled = False
Catch ex As Exception
con.Close()
MessageBox.Show(ex.Message)
End Try
end if
end if
end if
counting on you for your help. Thanks in advance!

Related

Database locked in vb.net when trying to update data in vb.net

Hello I have a simple method to update customer details in one of my database tables however when i try to update it an error occurs saying the database is locked. I have no idea how to fix this because my add and delete queries work just fine.
This is the error message:
System.Data.SQLite.SQLiteException: 'database is locked
database is locked'
Public Sub updateguest(ByVal sql As String)
Try
con.Open()
With cmd
.CommandText = sql
.Connection = con
End With
result = cmd.ExecuteNonQuery
If result > 0 Then
MsgBox("NEW RECORD HAS BEEN UPDATED!")
con.Close()
Else
MsgBox("NO RECORD HASS BEEN UPDATDD!")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
End Sub
Private Sub IbtnUpdate_Click(sender As Object, e As EventArgs) Handles ibtnUpdate.Click
Dim usql As String = "UPDATE Customers SET fname = '" & txtFName.Text & "'" & "WHERE CustomerID ='" & txtSearchID.Text & "'"
updateguest(usql)
End Sub
Private Sub IbtnSearch_Click(sender As Object, e As EventArgs) Handles ibtnSearch.Click
Dim sSQL As String
Dim newds As New DataSet
Dim newdt As New DataTable
Dim msql, msql1 As String
Dim con As New SQLiteConnection(ConnectionString)
con.Open()
msql = "SELECT * FROM Customers Where Fname Like '" & txtSearchName.Text & "%'"
msql1 = "SELECT * FROM Customers Where CustomerID '" & txtSearchID.Text & "'"
Dim cmd As New SQLiteCommand(msql, con)
Dim cmd1 As New SQLiteCommand(msql1, con)
Dim dt = GetSearchResults(txtSearchName.Text)
dgvCustomerInfo.DataSource = dt
Dim mdr As SQLiteDataReader = cmd.ExecuteReader()
If mdr.Read() Then
If txtSearchName.Text <> "" Then
sSQL = "SELECT * FROM customers WHERE fname LIKE'" & txtSearchName.Text & "%'"
Dim con1 As New SQLiteConnection(ConnectionString)
Dim cmd2 As New SQLiteCommand(sSQL, con1)
con1.Open()
Dim da As New SQLiteDataAdapter(cmd2)
da.Fill(newds, "customers")
newdt = newds.Tables(0)
If newdt.Rows.Count > 0 Then
ToTextbox(newdt)
End If
dgvCustomerInfo.DataSource = newdt
con1.Close()
txtSearchID.Clear()
ElseIf txtSearchID.Text <> "" Then
sSQL = "SELECT * FROM customers WHERE CustomerID ='" & txtSearchID.Text & "'"
Dim con2 As New SQLiteConnection(ConnectionString)
Dim cmd2 As New SQLiteCommand(sSQL, con2)
con2.Open()
Dim da As New SQLiteDataAdapter(cmd2)
da.Fill(newds, "customers")
newdt = newds.Tables(0)
If newdt.Rows.Count > 0 Then
ToTextbox(newdt)
End If
dgvCustomerInfo.DataSource = newdt
con2.Close()
txtSearchName.Clear()
End If
Else
MsgBox("No data found")
End If
End Sub
Private Sub IbtnDelete_Click(sender As Object, e As EventArgs) Handles ibtnDelete.Click
Dim dsql As String = "DELETE FROM customers WHERE customerid = " & txtSearchID.Text & ""
deleteme(dsql)
updatedgv(dgvCustomerInfo)
txtSearchID.Clear()
txtSearchName.Clear()
End Sub
Public Sub deleteme(ByVal sql As String)
Try
con.Open()
With cmd
.CommandText = sql
.Connection = con
End With
result = cmd.ExecuteNonQuery
If result > 0 Then
MsgBox("NEW RECORD HAS BEEN DELTED!")
con.Close()
Else
MsgBox("NO RECORD HASS BEEN DELTED!")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
End Sub
You made a good start on keeping your database code separate from you user interface code. However, any message boxes should be shown in the user interface and any sql statements should be written in the data access code.
I used Using...End Using blocks to ensure that database objects are closed and disposed. I used parameters to protect against sql injection. I am not too sure of the mapping of DbType types to Sqlite types. You might have to fool with that a bit. In you original Update statement you had the ID value in quotes. This would pass a string. When you use parameters, you don't have to worry about that or ampersands and double quotes. Just one clean string.
Private ConStr As String = "Your connection string"
Public Function updateguest(FirstName As String, ID As Integer) As Integer
Dim Result As Integer
Dim usql As String = "UPDATE Customers SET fname = #fname WHERE CustomerID = #ID;"
Using con As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(usql, con)
cmd.Parameters.Add("#fname", DbType.String).Value = FirstName
cmd.Parameters.Add("#ID", DbType.Int32).Value = ID
con.Open()
Result = cmd.ExecuteNonQuery
End Using
Return Result
End Function
Private Sub IbtnUpdate_Click(sender As Object, e As EventArgs) Handles ibtnUpdate.Click
Try
Dim Result = updateguest(txtFName.Text, CInt(txtSearchID.Text))
If Result > 0 Then
MsgBox("New RECORD HAS BEEN UPDATED!")
Else
MsgBox("NO RECORD HAS BEEN UPDATDD!")
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub

VB.NET:Updating record in Ms Access

I am creating an employee timing sheet in which they have to insert their timings through pressing timein and timeout buttons. For timein I am creating a new record in database, for that person, and for timeout I am using UPDATING command to update that existing record. Here is my code:
Dim cb As New OleDb.OleDbCommandBuilder(ssda)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
con.ConnectionString = dbProvider & dbSource
con.Open()
Dim str As String
str = "UPDATE emp_timing SET emp_timing.emp_timeout = '" & OnlyTime & "' WHERE (((emp_timing.emp_code)='" & TextBox1.Text & "') AND ((emp_timing.day)=" & Now.ToString("MM/dd/yyyy") & "))"
Dim cmd As OleDbCommand = New OleDbCommand(str, con)
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
con.Close()
MsgBox("Data added")
TextBox1.Clear()
TextBox2.Clear()
TextBox1.Focus()
ComboBox1.SelectedIndex = -1
Catch ex As Exception
MsgBox(ex.Message)
End Try
My code is working fine but the problem is that it is not updating records in database.
Datatype for fields in Access:
emp_code = Number, emp_timeout = Text, day = Date/Time.
As usual this is caused by your code not using the Parameters collection to pass values to the database engine. This is not really understood until you hit a conversion problem as always happens with dates
str = "UPDATE emp_timing SET emp_timeout = #p1 " & _
"WHERE emp_code = #p2 AND day = #p3"
Using con = new OleDbConnection( dbProvider & dbSource)
Using cmd = New OleDbCommand(str, con)
con.Open()
cmd.Parameters.Add("#p1", OleDbType.VarWChar).Value = OnlyTime
cmd.Parameters.Add("#p2", OleDbType.Integer).Value = Convert.ToInt32(TextBox1.Text)
cmd.Parameters.Add("#p3", OleDbType.Date).Value = new DateTime(Now.Year, Now.Month, Now.Day)
Try
Dim rowsAdded = cmd.ExecuteNonQuery()
if rowsAdded > 0 Then
MsgBox("Data added")
TextBox1.Clear()
TextBox2.Clear()
TextBox1.Focus()
ComboBox1.SelectedIndex = -1
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Using
End Using

how to save all record show in datagridview to the database

i have this code that will save only the top row of the datagridview,
can someone help me to modify this code so that it will save all the row in datagridview. im using vb 2010 and my database is ms access. thankyou in advance.
Try
Dim cnn As New OleDbConnection(conString)
query = "Insert into tblreportlog(EmpID,empname,department,empdate,timeinaM,timeoutam,lateam,timeinpm,timeoutpm,latepm,thw) values ('" & dgvReport.Item(0, dgvReport.CurrentRow.Index).Value & "', '" & dgvReport.Item(1, dgvReport.CurrentRow.Index).Value & "', '" & dgvReport.Item(2, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(3, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(4, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(5, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(6, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(7, dgvReport.CurrentRow.Index).Value & "', '" & dgvReport.Item(8, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(9, dgvReport.CurrentRow.Index).Value & "','" & dgvReport.Item(10, dgvReport.CurrentRow.Index).Value & "')"
cmd = New OleDbCommand(query, cnn)
cnn.Open()
cmd.ExecuteNonQuery()
cnn.Close()
Catch ex As Exception
MsgBox("ERROR: " & ErrorToString(), MsgBoxStyle.Critical)
End Try
Working from what is shown and best practices injected, you should be working from a data source such as a DataTable e.g. if when presented the DataGridView to the user there are no rows then create a new DataTable, set the DataTable as the DataSource of the DataGridView then when you are ready to save these rows in the DataGridView cast the DataSource of the DataGridView to a DataTable and use logic similar to the following
Dim dt As DataTable = CType(DataGridView1.DataSource, DataTable)
If dt.Rows.Count > 0 Then
Using cn As New OleDb.OleDbConnection With {.ConnectionString = "Your connection string"}
' part field list done here
Using cmd As New OleDb.OleDbCommand With
{
.Connection = cn,
.CommandText = "Insert into tblreportlog(EmpID,empname,department) values (#EmpID,#empname,#department)"
}
' TODO - field names, field types
cmd.Parameters.AddRange(
{
{New OleDb.OleDbParameter With {.ParameterName = "#EmpID", .DbType = DbType.Int32}},
{New OleDb.OleDbParameter With {.ParameterName = "#empname", .DbType = DbType.Int32}},
{New OleDb.OleDbParameter With {.ParameterName = "#department", .DbType = DbType.String}}
}
)
Dim Affected As Integer = 0
cn.Open()
Try
For Each row As DataRow In dt.Rows
' this should not be a auto-incrementing key
cmd.Parameters("#EmpID").Value = row.Field(Of Integer)("FieldName goes here")
cmd.Parameters("#empname").Value = row.Field(Of Integer)("FieldName goes here")
cmd.Parameters("#department").Value = row.Field(Of String)("FieldName goes here")
Affected = cmd.ExecuteNonQuery
If Affected <> 1 Then
Console.WriteLine("Error message, insert failed")
End If
Next
Catch ex As Exception
'
' handle exception
'
' for now
MessageBox.Show("Failed with: " & ex.Message)
' decide to continue or not
End Try
End Using
End Using
End If
On the other hand, if there are new rows with current rows we cast the data source as above then check for new rows along with validation as needed.
For Each row As DataRow In dt.Rows
If row.RowState = DataRowState.Added Then
If Not String.IsNullOrWhiteSpace(row.Field(Of String)("CompanyName")) Then
Other options, utilize a DataAdapter or setup data via data wizards in the ide where a BindingNavigator is setup with a save button.
If it's important to get the new primary key back the method for all methods can do this too.
The following code sample is from this MSDN code sample that shows how to get a new key back using OleDb connection and command.
Public Function AddNewRow(ByVal CompanyName As String, ByVal ContactName As String, ByVal ContactTitle As String, ByRef Identfier As Integer) As Boolean
Dim Success As Boolean = True
Try
Using cn As New OleDb.OleDbConnection(Builder.ConnectionString)
Using cmd As New OleDb.OleDbCommand("", cn)
cmd.CommandText = "INSERT INTO Customer (CompanyName,ContactName,ContactTitle) Values (#CompanyName,#ContactName,#ContactTitle)"
cmd.Parameters.AddWithValue("#CompanyName", CompanyName.Trim)
cmd.Parameters.AddWithValue("#ContactName", ContactName.Trim)
cmd.Parameters.AddWithValue("#ContactTitle", ContactTitle.Trim)
cn.Open()
cmd.ExecuteNonQuery()
cmd.CommandText = "Select ##Identity"
Identfier = CInt(cmd.ExecuteScalar)
End Using
End Using
Catch ex As Exception
Success = False
End Try
Return Success
End Function

autofilling textboxes with database data based on a primary key entry into another textbox

i have the code below, it works fine but whenever i insert a student number that does not exist in the table, the rest of the textboxes will keep displaying data from the previous existing entry. This happens even when the i delete everything in the student number textbox.
how can i change it such that the rest of the textboxes are cleared in case the student number textbox is blank or contains a student number that does not exist in the database?
Thanks in advance.
' Try
Dim mycommand As SqlCommand = New SqlCommand()
Dim datareader As SqlDataReader = Nothing
myconnection.Open()
Dim query As String
query = " select StudentNo,Fullname,Year,Term,Class from StudentRegistration where StudentNo = '" & TxtStudentNo.Text & "' and (class = 'Senior 5A' or Class ='Senior 5S' or Class='Senior 6A' or class='Senior1 6S')"
mycommand = New SqlCommand(query, myconnection)
datareader = mycommand.ExecuteReader()
While datareader.Read
If datareader IsNot Nothing Then
' TxtStudentNo.Text = datareader.Item("StudentNo")
TxtName.Text = datareader.Item("FullName")
TxtYear.Text = datareader.Item("Year")
TxtTerm.Text = datareader.Item("Term")
TxtClass.Text = datareader.Item("Class")
End If
End While
myconnection.Close()
' Catch ex As Exception
'MessageBox.Show(ex.Message)
' End Try`
Add an else condition to reader and clear text boxes in that module.
While datareader.Read
If datareader IsNot Nothing Then
' TxtStudentNo.Text = datareader.Item("StudentNo")
TxtName.Text = datareader.Item("FullName")
TxtYear.Text = datareader.Item("Year")
TxtTerm.Text = datareader.Item("Term")
TxtClass.Text = datareader.Item("Class")
else
TxtName.Text = ""
TxtYear.Text = ""
TxtTerm.Text = ""
TxtClass.Text = ""
End If
hope theres no big deal more than this.
I finally changed my code to the one below and it's doing exactly what i want.
Private Sub getData()
Dim dt As New DataTable()
myconnection.Open()
Dim Mycommand As New SqlCommand("select Fullname,Year,Term,Class from StudentRegistration where StudentNo = '" & TxtStudentNo.Text & "'", myconnection)
Dim sqlDa As New SqlDataAdapter(Mycommand)
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
TxtName.Text = dt.Rows(0)("FullName").ToString()
TxtYear.Text = dt.Rows(0)("Year").ToString()
Else
TxtName.Text = ""
TxtYear.Text = ""
End If
myconnection.Close()
End Sub

Populating Datagrid

I am creating a pageant scoring system,
I have this functions for populating my datagridview's first column using query:
Public Sub searchContestant()
If comboCategory.SelectedIndex <> 0 Then
Dim id As Integer = Login.JudgeBindingSource1.Current("Cont_id")
Dim critID As Integer = Convert.ToInt32(lblID.Text)
'search the contest record by the contest_id
Dim con As New SqlConnection
Dim reader As SqlDataReader
Dim reader2 As SqlDataReader
Dim dt = New DataTable()
Dim nc As New DataGridViewTextBoxColumn
DataGridView1.Columns.Clear()
DataGridView1.Rows.Clear()
Try
con.ConnectionString = "Data Source=BROWNIE\SQLEXPRESS;Initial Catalog=PSS;Integrated Security=True"
Dim cmd As New SqlCommand("SELECT * from Criteria where Cat_id = '" & critID & "' ", con)
Dim cmd2 As New SqlCommand("SELECT * from Contestant where Cont_id = '" & id.ToString() & "' ", con)
con.Open()
' Execute Query
reader = cmd.ExecuteReader()
nc.Name = "Contestants"
nc.Width = 250
nc.ReadOnly = True
DataGridView1.Columns.Add(nc)
While reader.Read()
nc = New DataGridViewTextBoxColumn
nc.Name = "(" & reader.GetString(2) & "%)" & reader.GetString(1)
nc.HeaderText = "(" & reader.GetString(2) & "%)" & reader.GetString(1)
nc.Width = 150
DataGridView1.Columns.Add(nc)
End While
Catch ex As Exception
MessageBox.Show("Error while connecting to SQL Server." & ex.Message)
Finally
con.Close() 'Whether there is error or not. Close the connection. '
End Try
Try
'populate contestant rows
con.ConnectionString = "Data Source=BROWNIE\SQLEXPRESS;Initial Catalog=PSS;Integrated Security=True"
Dim cmd2 As New SqlCommand("SELECT * from Contestant where Cont_id = '" & id.ToString() & "' ", con)
con.Open()
reader2 = cmd2.ExecuteReader()
While reader2.Read()
nc = New DataGridViewTextBoxColumn
nc.Width = 100
DataGridView1.Rows.Add(reader2.GetString(2).ToString())
End While
Catch ex As Exception
MessageBox.Show("Error while connecting to SQL Server." & ex.Message)
Finally
con.Close() 'Whether there is error or not. Close the connection. '
End Try
End If
End Sub
And for succeeding columns :
Public Sub searchCriteria()
Dim con As New SqlConnection
Dim reader4 As SqlDataReader
Dim dt = New DataTable()
Dim nc As New DataGridViewTextBoxColumn
DataGridView1.Columns.Clear()
Try
'populate Criteria
con.ConnectionString = "Data Source=BROWNIE\SQLEXPRESS;Initial Catalog=PSS;Integrated Security=True"
Dim cmd As New SqlCommand("SELECT * from Criteria where Cat_id = '" & lblID.Text & "' ", con)
con.Open()
reader4 = cmd.ExecuteReader
While reader4.Read
nc = New DataGridViewTextBoxColumn
nc.Name = reader4.GetString(1).ToString & Chr(13) & reader4.GetString(2).ToString & "%"
nc.Width = 100
DataGridView1.Columns.Add(nc)
End While
Catch ex As Exception
MessageBox.Show("Error while connecting to SQL Server." & ex.Message)
Finally
con.Close() 'Whether there is error or not. Close the connection. '
End Try
End Sub
This is the output:
And everytime a judge login, I insert data into the system with this function:
Public Sub makeTransaction()
Dim con2 As New SqlConnection
'get the judge id upon logging in
Dim judgeID = Login.JudgeBindingSource1.Current("Judge_id")
'get the contest id of the judge
Me.JudgeTableAdapter.FillByJudgeID(Me.PSSDataSet.Judge, judgeID)
Dim JudgeContestid = Login.JudgeBindingSource1.Current("Cont_id")
Me.ContestantTableAdapter.FillByContestID(Me.PSSDataSet.Contestant, JudgeContestid)
'get the contestant id
Me.ContestTableAdapter.FillByContestID(Me.PSSDataSet.Contest, JudgeContestid)
Dim contestID As Integer = ContestBindingSource.Current("Cont_id")
'get the category of the contest
Me.CategoryTableAdapter.FillByContestID(Me.PSSDataSet.Category, Convert.ToInt32(contestID))
For Each Category As DataRow In Me.PSSDataSet.Category.Rows
Me.CriteriaTableAdapter.FillByCategoryID(Me.PSSDataSet.Criteria, Category("Cat_id"))
For Each Contestant As DataRow In Me.PSSDataSet.Contestant.Rows
For Each Criteria As DataRow In Me.PSSDataSet.Criteria.Rows
TransactionsTableAdapter.Insert(JudgeContestid, Contestant("Con_id"), Criteria("Cri_id"), 0)
Next
Next
Next
End Sub
Now my problem is, how can I populate the datagrid using the data recently made by MakeTransaction() function?