vb.net - Object reference not set to an instance of object - vb.net

I got this error when trying to use parameters to my sql statement, but it works fine when not use it. My codes are below:
Dim i As String
Dim sql as String
sql = "SELECT * FROM tblStaff WHERE Username = #User AND Password = #Pass"
myCommand = New SqlCommand(sql, myConnection)
myCommand.Parameters.AddWithValue("#User", txtUser.Text)
myCommand.Parameters.AddWithValue("#Pass", txtPassword.Text)
i = myCommand.ExecuteScalar
txtUserType.Text = i.ToString
And when I comment on txtUserType.Text = i.ToString, it works fine. Any idea?

ExecuteScalar should only give you one value back, like an integer. So if you specify only one column in your SQL statement for example (Select usertype from tblStaff...) the executescalar should return an integer (if that column is a number).
Then it should work.
and by the way.. you don't have to use ToString on a variable that is a string. Just use the variables name
txtUserType.Text = i

Related

'No value given for one or more required parameters.' - System.Data.OleDb.OleDbException: [duplicate]

This question already has answers here:
How can I add user-supplied input to an SQL statement?
(2 answers)
'No value given for one or more required parameters.' Error, Can't get over it
(2 answers)
Closed 2 years ago.
I have the issue with the following function:
Public Function collectuserid(conn, username)
Dim sql As String = "select ID from tblUserDetails where Username =" & username
Dim usersid As String = Nothing
Using connection As New OleDbConnection(conn)
Using command As New OleDbCommand(sql, connection)
connection.Open()
usersid = CStr(command.ExecuteNonQuery())
connection.Close()
End Using
End Using
Return usersid
End Function
The problem occurs in the following line:
usersid = CStr(command.ExecuteNonQuery())
The variable conn holds the connection string, and username holds a value for the username present in the database.
I want to collect the userid of the record, but cant seem to get it right. I have the exact same function open in another program with a different database and it works perfectly. All table and variable names are correct also. Any help?
Program for generating the record:
Sub insertuservalues(conn, a, b, c, d)
Dim sql As String = "INSERT INTO tblUserDetails(Name,Username,[Password],Email) VALUES (#name, #username, #password, #email)"
Using connection As New OleDbConnection(conn)
Using command As New OleDbCommand(sql, connection)
connection.Open()
command.Parameters.Add("#name", OleDbType.VarWChar).Value = a
command.Parameters.Add("#username", OleDbType.VarWChar).Value = b
command.Parameters.Add("#password", OleDbType.VarWChar).Value = c
command.Parameters.Add("#email", OleDbType.VarWChar).Value = d
command.ExecuteNonQuery()
connection.Close()
End Using
End Using
End Sub
Strictly speaking, the mistake you made was that you didn't wrap your literal text value within the SQL code in single quotes. Just as VB literal text must be wrapped in double quotes, so SQL literal text must be wrapped in single quotes:
Dim sql As String = "SELECT ID FROM tblUserDetails WHERE Username = '" & username & "'"
or:
Dim sql As String = String.Format("SELECT ID FROM tblUserDetails WHERE Username = '{0}'", username)
or:
Dim sql As String = $"SELECT ID FROM tblUserDetails WHERE Username = '{username}'"
If you do it the right way though, and follow the advice to use parameters, this becomes redundant. ALWAYS use parameters to avoid formatting issues, special character issues and, most importantly, SQL injection issues.
You need single quotes around string values in the SQL. But don't do that! Instead, define this as a query parameter:
Public Function collectuserid(conn As String, username As String) As String
'No string concatentation!
' Also, OleDb tends to use ? placeholders for positional parameters, rather than parameter names.
Dim sql As String = "select ID from tblUserDetails where Username = ?"
Using connection As New OleDbConnection(conn)
Using command As New OleDbCommand(sql, connection)
'Use the actual type and length from the database here
command.Parameters.Add("username", OleDbtype.VarWChar, 20).Value = username
connection.Open()
Return CStr(command.ExecuteNonQuery())
'No need to call connection.Close()
' The Using block guarantees the connection will close, even though we Return before reaching the end of it.
End Using
End Using
End Function

Passing null value from textbox to sql query

I am new with VB.net. I am having problems passing a null value from a VB.net textbox to the sql query string. this is my current code:
Dim sqlstatement as string
If generic_jobTxt.Text == '' Then
generic_jobTxt = DBNull.Value
End If
sqlstatement = "Insert into Job_db (generic_job) values('"+generic_jobTxt+"')"
how can i pass a null value to the sql string so that when i run the sql i get a null value in the generic_job column. Thank you!
First, never concatenate strings to build your sql query, instead use parameterized queries. Otherwise you're open for sql injection and other issues.
On that way you also don't need to fiddle around with apostrophes. But you should use the correct types.
Presuming you're using SQL-Server and the column type is varchar:
Dim sqlstatement = "Insert into Job_db (generic_job) values(#generic_job)"
Using con As New SqlConnection("connection-string")
Using insertCommand = New SqlCommand(sqlstatement, con)
Dim sqlParam = New SqlParameter("#generic_job", SqlDbType.VarChar)
Dim jobTxt As String = generic_jobTxt.Text.Trim()
sqlParam.Value = If(String.IsNullOrEmpty(jobTxt), Nothing, jobTxt)
insertCommand.Parameters.Add(sqlParam)
con.Open()
Dim inserted As Int32 = insertCommand.ExecuteNonQuery()
End Using
End Using

Add the same parameter twice and execute query

Dim b as integer = 1
cmd = New SqlCommand
With cmd
.Connection = connecti
.CommandTimeout = 0
.CommandText = "INSERT INTO HEZDDD(ID,Number,Dates) VALUES (#Id,#Number,#Dates)"
With .Parameters
.AddWithValue("#ID", NextId())
.AddWithValue("#Dates", date.now)
If b = 1 Then
.AddWithValue("#Number", 1)
cmd.ExecuteNonQuery()
End if
If b>10 Then
.AddWithValue("#Number", 2)
cmd.ExecuteNonQuery()
End if
End With
End With
Looking forward to execute the same query twice using different parameters. The output of this simple query should be two rows.
This is simple example i didnt want to put entire code with around 25 parameters.
First use Parameters.Add(string parameterName, SqlDbType sqlDbType) to add parameters without values.
cmd.Parameters.Add("#ID", SqlDbType.Int);
Before you execute the command, provide the values for the parameters:
cmd.Parameters["#ID"].Value = NextId();
Actually, it's always better to use Parameters.Add(string parameterName, SqlDbType sqlDbType), even if you want to set the value immediately. If you use AddWithValue, the db type of the parameter has to be inferred from the value. It usually works well, but you might have some surprises. And because Add returns the added parameter, you can assign the value in the same line:
cmd.Parameters.Add("#ID", SqlDbType.Int).Value = NextId();
It's already in the parameter collection, you just need to change the value on it on the second one.
.Parameters("#Number").Value = 2
Or out of the with..
cmd.Parameters("#Number").Value = 2

SQLite SELECT from VB.Net application (Win32)

I am trying to get a result from SQL database and keep it as a variable. But with my code (see below) it returns 0 (zero). Any ideas of what am i doing wrong?
Thanks
Function getName(name As String)
Dim SQLconnect As New SQLite.SQLiteConnection()
Dim SQLcommand As SQLite.SQLiteCommand
SQLconnect.ConnectionString = "Data Source=C:\tools\names.sqlite;"
SQLconnect.Open()
SQLcommand = SQLconnect.CreateCommand
SQLcommand.CommandText = "SELECT * FROM names WHERE name = " & name & " LIMIT 1;"
Dim sqlResponse As String = SQLcommand.ExecuteNonQuery()
End Function
EDIT: I am using "return sqlResponse" for return
First thing, the sql should be(I think):
SQLcommand.CommandText = "SELECT * FROM names WHERE name = '" & name & "' LIMIT 1;"
I am not sure how text is represented in SQLite but you need some kind of delimiter like a single quote in SQL Server.
Second thing, use paramterized query to stop yourself from being hijacked by SQL Injections
Third, a SELECT uses a ExecuteReader, and in case where you want only one item, try ExecuteScalar. ExecuteNonQuery is for insert, update delete.
ExecuteNonQuery does not return a value so therefore it will always be 0. You need to use
Dim sqlResponse As String = SQLcommand.ExecuteScalar()

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.