I have done data validation.So now when proper data is not entered it will show an message box showing error but also it shows the following message box where i want to block or hide the message box from popping up. Here is my code below. Please show me my error and give me a solution. Thanks
Dim digit As Integer
Dim text As String
Try
digit = CInt(txtsid.Text) & CInt(txtsph.Text)
Text = CStr(txtsfn.Text) & CStr(txtsln.Text) & CStr(txtsem.Text) & CStr(txtint.Text)
Catch ex As Exception
MessageBox.Show("Please Type In A Proper Information")
End Try
Dim result As Integer = MessageBox.Show("Are you sure you want to proceed?", "Proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If result = DialogResult.Yes Then
cmdInsert.CommandText = "Insert into student Values(" + txtsid.Text + ",'" + txtint.Text + "','" + txtsfn.Text + "','" + txtsln.Text + "', '" + cmbgen.Text + "', " + txtsph.Text + ", '" + txtsem.Text + "');"
cmdInsert.CommandType = CommandType.Text
cmdInsert.Connection = cnnOLEDB
cmdInsert.ExecuteNonQuery()
UserHomepage.Show()
Me.Hide()
ElseIf result = DialogResult.No Then
Me.Show()
UserHomepage.Hide()
End If
End Sub
Simply Return or Exit Sub to exit the Sub:
Try
digit = CInt(txtsid.Text) & CInt(txtsph.Text)
Text = CStr(txtsfn.Text) & CStr(txtsln.Text) & CStr(txtsem.Text) & CStr(txtint.Text)
Catch ex As Exception
MessageBox.Show("Please Type In A Proper Information")
Return ' --- here
End Try
That would end execution of the whole Sub (function, method, whatever you want to call it in VB) and return control back to the caller.
Note: There's a better way to do what you're trying to do. One should not use exceptions for logic flow. And parsing integers is logic flow. Instead of using CInt() and checking for exceptions, take a look at Int32.TryParse(). For example:
Dim sid As Int32
Dim result As Boolean = Int32.TryParse(txtsid.Text, sid)
If Not result
' show error
End If
It may end up being more code, but that's not inherently a bad thing. It's still better code.
And I don't think you need to call CStr() on things which are already strings...
Also Note: Your code is wide open to something called SQL Injection. Take a look at how (and why) to create Parameterized Queries (in other environments often called Prepared Statements). Basically, whereas you currently execute user input as code, you should instead treat user input only as values.
Related
I use Microsoft Access to store the data. The register form shows msgbox that the data was saved but there isn't any data stored in the table when I check the table on Microsoft Access. Is it supposed to be like that or did I code wrong?
This is my register code
If PasswordTextBox.Text.Length >= 8 Then
Try
Dim conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database2.accdb")
Dim insert As String = "Insert into Table1 values('" & NameTextBox.Text & "','" & Staff_IDTextBox.Text & "','" & Phone_NoTextBox.Text & "','" & UsernameTextBox.Text & "','" & PasswordTextBox.Text & "');"
Dim cmd As New OleDbCommand(insert, conn)
conn.Open()
'cmd.ExecuteNonQuery()
MsgBox("Saved")
For Each txt As Control In Me.Controls.OfType(Of TextBox)()
txt.Text = ""
Next
Catch ex As Exception
MsgBox("Error")
End Try
Else
MsgBox("Password must be more than 8 character")
End If
End If
This is my login code
uname = UsernameTextBox.Text
pword = PasswordTextBox.Text
Dim query As String = "Select password From Table1 where name= '" & uname & "';"
Dim dbsource As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database2.accdb"
Dim conn = New OleDbConnection(dbsource)
Dim cmd As New OleDbCommand(query, conn)
conn.Open()
Try
pass = cmd.ExecuteScalar().ToString
Catch ex As Exception
MsgBox("Username does not exit")
End Try
If (pword = pass) Then
MsgBox("Login succeed")
Else
MsgBox("Login failed")
UsernameTextBox.Clear()
PasswordTextBox.Clear()
End If
There is an error at this line
pass = cmd.ExecuteScalar().ToString
It says:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Your "cmd.ExecuteNonQuery" is commented out, so the code will not save anything to the database.
You should close your connection after executing the INSERT command.
By default the table will have auto-numbered field as the first item in the table. You will need to remove this field from your table for that specific INSERT command to work.
Or you may need to use a slightly different INSERT command. It is useful to have auto-numbered ID fields in a table.
You probably should catch the exception and display ex.Message in your message box rather then "Error". The ex.Message will be much more helpful to you in debugging your program.
I have made all of these mistakes in my code at one time or other.
Your Login Code;
1)
You should catch the exception message and display in it a message box. This will make debugging faster.
The actual exception in your code will read "{"No value given for one or more required parameters."}
Your query is incorrect.
You should do the open, query, and close of the connection inside the Try-Catch block. Test for a null password afterwards to determine if the username does not exist.
Two separate answers provided, because you have two very separate questions.
Best wishes...
I'm trying to send many or bulk sms using AT Command. I try send all number inside the datagrid but only first number is sending.
this is my code
Dim sql As New MySqlDataAdapter("select StudentID, StudentName,StudentContact, DueDate FROM issue inner join student on student.StudentID = issue.Student ", conn)
Dim ds As New DataSet
sql.Fill(ds, 0)
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
Dim wholenum As String
Dim wholesms As String
wholenum = ds.Tables(0).Rows(i).Item(2).ToString
wholesms = "Hello " & ds.Tables(0).Rows(i).Item(1).ToString & ", this is your Due Date " & ds.Tables(0).Rows(i).Item(3).ToString & " pls return it on your due date"
If SerialPort1.IsOpen Then
Try
With SerialPort1
.Write("AT" & vbCrLf)
.Write("AT+CMGF=1" & vbCrLf)
.Write("AT+CMGS=" & Chr(34) & wholenum & Chr(34) & vbCrLf)
.Write(wholesms & Chr(26))
MsgBox("Success sa SEND")
'update one
'Call ConnectDatabase()
'com = New MySqlCommand("UPDATE issue SET Sent='1' ", conn)
'com.ExecuteNonQuery()
'Call DisconnectDatabase()
End With
Catch ex As Exception
MsgBox("Bad Signal or No load")
End Try
Else
MsgBox("Pls insert a modem")
End If
I think the looping is working 'cuz it apppears the successful message of how many inside in the datagrid view. But it only send the first number.
You need to fix your AT command handling significantly. First of all you need to read and parse everything the modem sends back to you after sending a AT command line (which by the way should be terminated with just "\r" and not vbCrLf).
You should never start sending a new command line before you have received the Final result code. And for AT+CMGS specifically you should never send the sms payload before you have received the "\r\n >" prefix.
These issues are covered in this and this answer. But the very first thing you should to is to read all of the text in chapter 5 in the V.250 specification. It is a really important document when working with AT commands.
I'm writing a program in Visual Basic about Databases. Now I have a Sub/Function who searches the database for correct inputs. I have five text boxes where the user can put in something for each data field.
If txtBox1.Text <> "" Or txtBox2.Text <> "" Or txtBox3.Text <> "" Or txtBox4.Text <> "" Or txtBox5.Text <> "" Then
Try
connection.Open()
command.CommandText = "SELECT * from lager WHERE (lager_waren_id LIKE '" & txtBox1.Text & "' OR lager_warenanzahl LIKE '" & txtBox2.Text & "' OR lager_warenname LIKE '%" & txtBox3.Text & "%' OR lager_warengewicht LIKE '" & txtBox4.Text & "%' OR lager_waren_verkaufspreis LIKE '" & txtBox5.Text & "%');"
reader = command.ExecuteReader()
FormKunde.Enabled = True
FormKunde.lstViewKundeStore.Items.Clear()
Do While reader.Read()
Dim lstViewItem As New ListViewItem(reader("lager_waren_id").ToString())
lstViewItem.SubItems.Add(reader("lager_warenanzahl").ToString())
lstViewItem.SubItems.Add(reader("lager_warenname").ToString())
lstViewItem.SubItems.Add(reader("lager_warengewicht").ToString())
lstViewItem.SubItems.Add(reader("lager_waren_verkaufspreis").ToString())
FormKunde.lstViewKundeStore.Items.Add(lstViewItem)
Loop
reader.Close()
FormKunde.Enabled = False
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
connection.Close()
Else
MessageBox.Show("Please fill in something in the text fields")
Exit Sub
End If
I'm aksing the database if at least one text field has some input that matches to the data field it belongs to. But when I put something in, doesn't matter how much, nothing happens in my list view. It just loads all data back in the list view. When I try to do "AND" instead of "OR", it works only if i fill all text fields with the correct datas for one data set. But I want, that it finds all data sets.
An example:
I have two data sets where the names are "App" and "Apple". When i just fill in "Ap" in the field for names (nothing in the others) it shows me both. I think it should work with "OR", but it just does nothing.
I'm really confused how to solve this, I hope anyone has a guess. Thank you!
Your problem is that your query always uses all the conditions also when there is no input in the relevant textboxes. In this way your LIKEs become LIKE '%%' and, of course, this matches every record.
You need to add the conditions only if the textboxes are not empty or null.
So you need to build your query in parts after checking if the textbox contains any value to search for.
connection.Open()
Dim sql = "SELECT * from lager WHERE "
if Not string.IsNullOrWhiteSpace(textBox1.Text) Then
sql = sql & "lager_waren_id LIKE #p1 OR "
command.Parameters.AddWithValue("#p1", textBox1.Text)
End If
if Not string.IsNullOrWhiteSpace(textBox2.Text) Then
sql = sql & "lager_warenanzahl LIKE #p2 OR "
command.Parameters.AddWithValue("#p2", textBox2.Text)
End If
if Not string.IsNullOrWhiteSpace(textBox3.Text) Then
sql = sql & "lager_warenname LIKE #p3 OR "
command.Parameters.AddWithValue("#p3", "%" & textBox3.Text & "%")
End If
if Not string.IsNullOrWhiteSpace(textBox4.Text) Then
sql = sql & "lager_warengewicht LIKE #p4 OR "
command.Parameters.AddWithValue("#p4", textBox4.Text & "%")
End If
if Not string.IsNullOrWhiteSpace(textBox5.Text) Then
sql = sql & "lager_waren_verkaufspreis LIKE #p5 OR "
command.Parameters.AddWithValue("#p5", textBox5.Text & "%")
End If
' Remove the last OR if any ....'
if sql.EndsWith(" OR ") then
sql = sql.Substring(0, sql.Length - 4)
End If
' Remove the WHERE if no textbox has been filled....'
if sql.EndsWith(" WHERE ") then
sql = sql.Substring(0, sql.Length - 7)
End If
command.CommandText = sql
reader = command.ExecuteReader()
Notice also that you should ALWAYS use a parameterized query to avoid Sql Injection particularly when you get your inputs directly from your user. (Not to mention the problems with typed texts that contain a single quote)
I hope I understand your problem correctly. I am sure there are better ways to do this and my VB is rusty but something like this may work
Dim query As String = "SELECT * FROM lager"
Function addField (ByVal query As String, ByVal value as String, ByVal field as String) As String
addField = query
If value <> "" Then
If query.IndexOf("where", 0, StringComparison.CurrentCultureIgnoreCase) > -1 Then
addField = query & " AND " & field & " LIKE '%" & value & "%'"
Else
addField = query & " WHERE " & field & " LIKE '%" & value & "%'"
End If
End If
End Function
query = addField(query, txtBox1.Text, "lager_waren_id")
query = addField(query, txtBox2.Text, "lager_warenanzahl")
'...continue adding fields...'
command.CommandText = query
This should make it so your query string only includes the populated fields
This code works. It's based on some code I found on the internet.
Can you tell me if the coding is the best way to get a scalar value and if there is a better way can you show coding samples?
Dim objParentNameFound As Object
TextBoxParentsName.Text = ""
If TextBoxParentID.Text <> "" Then
' Display the parent's name using the parent ID. '
Dim strSqlStatement As String = "Select FatherName " & _
"From Parents " & _
"Where ID = #SearchValue"
' Set up the sql command and lookup the parent. '
Using objSqlCommand As SqlCommand = New SqlCommand(strSqlStatement, ObjConnection)
With objSqlCommand
' Add SqlParameters to the SqlCommand. '
.Parameters.Clear()
.Parameters.AddWithValue("#SearchValue", TextBoxParentID.Text)
' Open the SqlConnection before executing the query. '
Try
ObjConnection.Open()
Try
objParentNameFound = .ExecuteScalar()
If objParentNameFound <> Nothing Then
' Display the parent name here. '
TextBoxParentsName.Text = objParentNameFound
End If
Catch exSqlErrors As SqlException
MessageBox.Show("Sorry, I couldn't execute your query because of this error: " & _
vbCrLf & vbCrLf & exSqlErrors.Message, _
"Error")
End Try
Catch exErrors As Exception
MessageBox.Show("Sorry, there was an error. Details follow: " & _
vbCrLf & vbCrLf & exErrors.Message, _
"Error")
Finally
ObjConnection.Close()
End Try
End With
End Using
End If
The Microsoft Access Application block has some nice examples of how to use ADO.Net. In particular what you might find helpful is how they've organized tasks such as ExecuteScalar() into a series of overloaded methods making it easy to invoke the process you need.
The sample you posted would greatly benefit from separating out the concerns. In other words, take the code you use to build up the connection, command and parameters and make that a separate method or methods. This allows the code to be reused without copy& pasting it throughout your codebase. This allows your calling code to simply pass in the parameter(s) and bind the result to your text box or other controls.
Edit: Example
Assuming you use the SqlHelper.vb class you can do something like the following:
Dim searchValue As Integer = 1
Dim myConnectionString As String = "MyConnectionString"
Dim sqlStatement As String = "SELECT FatherName FROM Parents WHERE ID = #SearchValue"
Dim paramList(0) As SqlParameter
paramList(0) = New SqlParameter() With {.Value = searchValue, .ParameterName = "#SearchValue"}
TextBoxParentsName.Text = SqlHelper.ExecuteScalar(myConnectionString, CommandType.Text, sqlStatement, paramList).ToString()
I'm sure this question will be easy for you lot... :)
I'm simply trying to update an existing record in my database using the following:
Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click
If Not cnn.State = ConnectionState.Open Then
cnn.Open()
End If
cmd2.Connection = cnn
cmd2.CommandText = "UPDATE HireItemRecord SET HireItemBeginDate = " & TextBox45.Text & _
" ,HireItemEndDate = " & TextBox44.Text & _
" ,HireItemCost = " & TextBox16.Text & _
" ,PaymentMethod = " & TextBox17.Text & _
" ,Staff_Id = " & TextBox19.Text & _
" ,HireItemNotes = " & TextBox18.Text & _
" ,HireItemReturnDate = " & TextBox43.Text & _
"WHERE HireRecord_Id = " & TextBox13.Text
cmd2.ExecuteNonQuery()
ds1.Clear()
daHireItemRecord.Fill(ds1, "PersonDetails")
cnn.Close()
End Sub
However no matter what record is selected and whatever details are in the boxes I keep getting this same error over and over:
SqlException was unhandled
Incorrect syntax near '12'.
When there is absolutely nothing in the textboxes the error changes to:
Incorrect syntax near ','.
I'm very new to this and I just can't seem to understand why this is happening.
Thank you very much for your help. :)
So much wrong with this.
You need a space after each comma, not before it.
You should be escaping your values before using them in the query. If I put "0 WHERE 1=1 -- " in any of your text boxes, it'll trash your entire table.
You should ALWAYS name your form controls properly. If I sent you back to this code in a year's time and told you there was a problem with TextBox44, would you know what it means? Same goes for your variables. Sometimes it's ok to have i, x or tbl for a variable name, but in general they should be descriptive.
Example for #2, where I've put "'1/1/1999' WHERE 1=1 --" into TextBox45:
`UPDATE HireItemRecord SET HireItemBeginDate = '1/1/1999' WHERE 1=1 -- , HireItemEndDate...`
Everything after the -- becomes a comment, so you get this:
`UPDATE HireItemRecord SET HireItemBeginDate = '1/1/1999' WHERE 1=1`
Can you imagine what would happen if I executed that query? Nothing good.
You should use parameterized queries, as per the recommendations in this question: Algorithm to avoid SQL injection on MSSQL Server from C# code?
You should never use string concatenation to build SQL. It leaves you open to SQL Injection attacks. Try using the SQLCommand object provided in .Net. This allows you to "parameterize" your query and you don't have to worry about where to put " and '.
It will also allow you add parameters naturally without having to convert them to strings. Something like this:
Dim command As New SqlCommand("SELECT * FROM Table", connection)
command.Parameters.Add("#ID", SqlDbType.Int)
command.Parameters("#ID").Value = customerID
I stole that code from the documentation about SQL Parameters here.