the user must match to the 3 fields - vb.net

Dim elem As String
elem = "Grade School"
Dim v As Integer
v = 0
Dim con As New SqlConnection("SERVER=ANINGDZTS-PC;DATABASE=AEVS;Trusted_Connection = yes;")
Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM tbl_Voter WHERE Department, VotersID = '" & elem & "''" & txt_PwordElem.Text & "'AND Voted ='" & v & "'", con)
con.Open()
Dim sdr As SqlDataReader = cmd.ExecuteReader()
Try
If (sdr.Read() = False) Then
high()
Else
MessageBox.Show("WELCOME!")
elemBallot.Show()
Me.Hide()
End If
Catch EX As Exception
MsgBox(EX.Message)
End Try
End Sub
this code is not working, an error appear," An expression of non-boolean type specified in a context where a condition is expected, near ','."

Instead of trying to create your SQL query via concatenating strings, which is prone to errors, a much better way is to use parametrized query. Change your SqlCommand declaration to
Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM tbl_Voter WHERE Department = #Department AND VotersID = #VotersID AND Voted = #Voted", con)
cmd.Parameters.AddWithValue("#Department", elem)
cmd.Parameters.AddWithValue("#VotersID", txt_PwordElem.Text)
cmd.Parameters.AddWithValue("#Voted", v)
Bonus: Avoid SQL Injection
P.S. Please don't forget to close your Reader and Connection after the use.
P.P.S. If you simple need to make sure that specific row in table "tbl_Voter" exists or not based on your parameters (which is, judging by the code what you're doing) - using DataReader is overkill. Consider query like SELECT 1 FROM tbl_Voter ... and use of ExecuteScalar to check returned value for Nothing

Related

How do I read HasRow then Update?

Is it possible to read HasRow and then Update ?
This is the code what I have tried so far :
If conn.State = ConnectionState.Closed Then
conn.Open()
End If
Dim sqlcmd As New MySqlCommand("SELECT * FROM tbl_online_attendance where employees_id = '" & lvRealAtt.Items(itms).SubItems(0).Text & "' and in_time = '" & lvRealAtt.Items(itms).SubItems(1).Text & "' ", conn)
Dim dr As MySqlDataReader
dr = sqlcmd.ExecuteReader
If dr.HasRows Then
Dim query As String
query = "UPDATE tbl_online_attendance SET out_time = '" & lvRealAtt.Items(itms).SubItems(2).Text & "' where employees_id = '" & lvRealAtt.Items(itms).SubItems(0).Text & "' and in_time = '" & lvRealAtt.Items(itms).SubItems(1).Text & "' "
sqlcmd.Connection = conn
sqlcmd.CommandText = query
sqlcmd.ExecuteNonQuery() 'It error in this part
Else
End If
But it give's me error saying:
There is already an open DataReader associated with this Connection which must be closed first
Please avoid commenting Use Parameters Your code is Prone to SQL injection attack
You should not have to check connection state if you keep your connections local to the method that they are used. Database objects like connections and commands need to be closed and disposed as soon as possible. Using...End Using blocks take care of this for you even if there is an error. Don't open a connection until directly before the .Execute....
Don't pull down data when you only need Count. .ExecuteScalar returns the first column of the first row of the result set, which in this case, is the Count. If you have a large table you need to look into If Exists which will stop as soon it finds a match whereas Count looks at the whole table.
Always use Parameters. Never concatenate strings to build sql queries to avoid sql injection. I had to guess at the datatypes of the parameters. Check your database to get the actual types and adjust the code accordingly.
Private Sub OPCode(ByVal itms As Integer)
Dim RowCount As Integer
Using conn As New MySqlConnection("Your connection string"),
sqlcmd As New MySqlCommand("SELECT Count(*) FROM tbl_online_attendance where employees_id = #id and in_time = #inTime;", conn)
sqlcmd.Parameters.Add("#id", MySqlDbType.Int32).Value = CInt(lvRealAtt.Items(itms).SubItems(0).Text)
sqlcmd.Parameters.Add("#inTime", MySqlDbType.String).Value = lvRealAtt.Items(itms).SubItems(1).Text
conn.Open()
RowCount = CInt(sqlcmd.ExecuteScalar)
If RowCount > 0 Then
sqlcmd.CommandText = "UPDATE tbl_online_attendance SET out_time = #outTime where employees_id = #id and in_time = #inTime;"
sqlcmd.Parameters.Add("#outTime", MySqlDbType.String).Value = lvRealAtt.Items(itms).SubItems(2).Text
sqlcmd.ExecuteNonQuery()
End If
End Using
End Sub
Every SqlDataReader needs to be closed before you could execute another query.
so i suggest you to separate the sqlreader and the update query, put the reader into a boolean function to check either a row with those parameters exist or not.
Private Function HasRow(ByVal employeeid As Integer, ByVal date as DateTime) As Boolean
HasRow = False
Dim reader As SqlDataReader
'do select query here
'use the if reader.Read if you want to
HasRow = reader.HasRows
reader.Close()
End Function
Call the function before updating, if it's True then proceed the update. Let's say we put it into a Update Sub.
Private Sub Update()
If HasRows(parameters here) Then
'update query here
End If
End Sub

Converting VBA function to VB.net to get sql data

I am trying to convert VBA code into VB.net and I have made it to a point but I can't convert resultset into vb.net. RS was 'dim as resultset' in VBA, thought i could just change it to dataset but am getting errors with the '.fields' and other options?
Function GetG(sDB As String, sServ As String, sJob As String) As String
'sDB = Database name, sServ = Server\Instance, path = job.path
Dim conString As String = ("driver={SQL Server};server = " &
TextBox1.Text & " ; uid = username;pwd=password:database = " &
TextBox2.Text)
Dim RS As DataSet
Dim conn As SqlConnection = New SqlConnection(conString)
Dim cmd As SqlCommand
conn.Open()
'This is where my problems are occuring
cmd = New SqlCommand("SELECT [ID],[Name] FROM dbo.PropertyTypes")
Do While Not RS.Tables(0).Rows.Count = 0
If RS.Fields(1).Value = sJob Then
GetG = RS.Fields(0).Value
GetG = Mid(GetG, 2, 36)
Exit Do
End If
DataSet.MoveNext
Loop
conn.Close
End Function
Based on my understanding and some guesswork, here is what I came up with for what I think you're wanting.
As I stated in my comment above, it appears you can just use a WHERE clause to get the exact record you want (assuming a single instance of sJob appears in the name column).
Build the connectionstring off the input arguments, not controls on your form. That is after all why you allow for arguments to be passed along. Also note that there is a SqlCommandBuilder object that may be of interest. But for now
Function GetG(sDB As String, sServ As String, sJob As String) As String
'we'll pretend your connectionstring is correct based off of the sDB and sServ arguments
Dim conStr As String = ("driver={SQL Server};server = " & sServ & " ; uid = username;pwd=password:database = " & sDB)
'Create a connection and pass it your conStr
Using con As New SqlConnection(conStr)
con.Open() 'open the connection
'create your sql statement and add the WHERE clause with a parameter for the input argument 'sJob'
Dim sql As String = "SELECT [ID], [Name] FROM dbo.PropertyTypes WHERE [Name] = #job"
'create the sqlCommand (cmd) and pass it your sql statement and connection
Using cmd As New SqlCommand(sql, con)
'add a parameter so the command knows what #job holds
cmd.Parameters.Add(New SqlParameter("#job", SqlDbType.VarChar)).Value = sJob
'Now that have the command built, we can pass it to a reader object
Using rdr As SqlDataReader = cmd.ExecuteReader
rdr.Read()
'i admin i'm a little confused here on what you are
'trying to achieve so ID may not be what you are
'really wanting to get a substring of.
Return rdr("ID").ToString.Substring(2, 36)
End Using
End Using
End Using
End Function
An example to see if this is working could be to call a messagebox do display the result. For this example, I'm going to pretend that TextBox3 holds the sJob you're wanting. With that knowledge, you could simply do:
MessageBox.Show(GetG(TextBox2.Text, TextBox1.Text, TextBox3.Text))
This should then produce the result in a messagebox.
It seems that you're not filling your DataSet. So, when you try to loop through it, it's uninitialized or empty.
Check this answer to see an example: Get Dataset from DataBase

Visual basic - Incrementing the score

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim READER As MySqlDataReader
Dim Query As String
Dim connection As MySqlConnection
Dim COMMAND As MySqlCommand
Dim item As Object
Try
item = InputBox("What is the item?", "InputBox Test", "Type the item here.")
If item = "shoe" Then
Dim connStr As String = ""
Dim connection As New MySqlConnection(connStr)
connection.Open()
Query = "select * from table where username= '" & Login.txtusername.Text & " '"
COMMAND = New MySqlCommand(Query, connection)
READER = COMMAND.ExecuteReader
If (READER.Read() = True) Then
Query = "UPDATE table set noOfItems = noOfItems+1, week1 = 'found' where username= '" & Login.txtusername.Text & "'"
Dim noOfItems As Integer
Dim username As String
noOfItems = READER("noOfItems") + 1
username = READER("username")
MessageBox.Show(username & "- The number of items you now have is: " & noOfGeocaches)
End If
Else
MsgBox("Unlucky, Incorrect item. Please see hints. Your score still remains the same")
End If
Catch ex As Exception
MessageBox.Show("Error")
End Try
I finally got the message box to display! but now my code does not increment in the database, can anybody help me please :D
Thanks in advance
After fixing your typos (space after the login textbox and name of the field retrieved) you are still missing to execute the sql text that updates the database.
Your code could be simplified understanding that an UPDATE query has no effect if the WHERE condition doesn't find anything to update. Moreover keeping an MySqlDataReader open while you try to execute a MySqlCommand will trigger an error in MySql NET connector. (Not possible to use a connection in use by a datareader). We could try to execute both statements in a single call to ExecuteReader separating each command with a semicolon and, of course, using a parameter and not a string concatenation
' Prepare the string for both commands to execute
Query = "UPDATE table set noOfItems = noOfItems+1, " & _
"week1 = 'found' where username= #name; " & _
"SELECT noOfItems FROM table WHERE username = #name"
' You already know the username, don't you?
Dim username = Login.txtusername.Text
' Create the connection and the command inside a using block to
' facilitate closing and disposing of these objects.. exceptions included
Using connection = New MySqlConnection(connStr)
Using COMMAND = New MySqlCommand(Query, connection)
connection.Open()
' Set the parameter value required by both commands.
COMMAND.Parameters.Add("#name", MySqlDbType.VarChar).Value = username
' Again create the reader in a using block
Using READER = COMMAND.ExecuteReader
If READER.Read() Then
Dim noOfItems As Integer
noOfItems = READER("noOfItems")
MessageBox.Show(username & "- The number of items you now have is: " & noOfItems )
End If
End Using
End Using
End Using

Using results of a SqlDataReader in a SQL query

I would like to get the results of my reader to be able to be used in a WHERE clause in another SQL command. I have tried to put the reader into a variable to use but it does not work. I've never used readers before so I do not know how they work. Can anyone give me an idea of how to get the result of the reader into there where statement? Thanks.
The code:
Dim courseSelectCom = New SqlCommand("select stuff((select ','+course_name from course where school= '" & schoolSelect & "' for xml path ('')), 1, 1, '')", connection)
Dim reader = courseSelectCom.ExecuteReader()
If reader.Read() Then
Dim courseVar As String
courseVar = "%" & reader("course_name") & "%"
Using totalStudentCom = New SqlCommand("SELECT COUNT(student_ID) FROM student " & "course_name like #course", connection)
totalStudentCom.Parameters.AddWithValue("#course", courseVar)
Dim result = totalStudentCom.ExecuteScalar()
MessageBox.Show("Students for course = " & result.ToString)
End Using
End If
There are a couple of problems here.
First you should use parametrized query and not string concatenations for building sql commands
Second when a DataReader is opened, the connection object cannot serve another command unless you have specified the substring MultipleActiveResultSets=True; in your connection string
Dim courseSelectCom = New SqlCommand("select course_name from course where school= #school", connection)
courseSelectCom.Parameters.AddWithValue("#school", schoolSelect)
Dim reader = courseSelectCom.ExecuteReader()
if reader.Read() then
Dim courseVar As String
courseVar = "%" & reader("course_name") & "%"
Using totalStudentCom = new SqlCommand("SELECT COUNT(student_ID) FROM student " & _
"course_name like #course", connection)
totalStudentCom.Parameters.AddWithValue("#course", courseVar)
Dim result = totalStudentCom.ExecuteScalar()
MessageBox.Show("Students for course = " & result.ToString)
End Using
End If
Remember that this works only if MARS is enabled

Selecting an integer from an Access Database using SQL

Trying to select an integer from an Access Database using an SQL statement in VB
Dim cmdAutoTypes As New OleDbCommand
Dim AutoTypesReader As OleDbDataReader
cmdAutoTypes.CommandText = "SELECT * FROM AutoTypes WHERE TypeId = '" & cboTypeIds.Text & "'"
AutoTypesReader = cmdAutoTypes.ExecuteReader
Error message says: "OleDbException was unhandled: Data type mismatch in criteria expression." and points to the AutoTypesReader = cmdAutoTypes.ExecuteReader line
Rather make use of OleDbParameter Class
This will also avoid Sql Injection.
You don't need the quotes in the query string. You're searching for a number, not a string.
cmdAutoTypes.CommandText = "SELECT * FROM AutoTypes WHERE TypeId = " & cboTypeIds.Text
Hi In access SQL you can't use single quote around your Integer type.
so
command text will be.. "SELECT * FROM AutoTypes WHERE TypeId = " & cboTypeIds.Text & " and .... "
In Access SQL, don't quote numeric constants.
And test whether IsNull(cboTypeIds). You can't do what you were planning to do until a value has been chosen.
Do not use string concatenation when you build your SQL query, use parameters instead.
Dim cmd As OledbCommand = Nothing
Dim reader as OleDbDataReader = Nothing
Try
Dim query As String = "SELECT * FROM AutoTypes WHERE TypeId = #Id"
cmd = New OledbCommand(query, connection)
//adding parameter implicitly
cmd.Parameters.AddWithValue("#Id", cboTypeIds.Text)
reader = cmd.ExecuteReader()
Catch ex As Exception
Messagebox.Show(ex.Message, MsgBoxStyle.Critical)
End Try
You can also explicitly state the parameter data type.
cmd.Parameters.Add("#Id", OleDbType.Integer).Value = cboTypeIds.Text
Hope this helps.