How to Pass GridView Values to SQLCommand Parameters in VB.net - vb.net

I have data in a GridView that is being approved by the user for specific data periods (StartDate, ex. '2017-05-01). For each row, if the checkbox for the row is checked, the record is approved and timestamped. If the box is not checked, the record is marked with a 'D' and timestamped. Comments are required on unapproved records but not on approved records.
The problem is that I can't get my update statements to run, and I believe that it's because of the way I'm setting the parameters or StartDate, FileNumber and EmpID. I tried running simple DELETE statements based on UserName and EmpID, and those worked. Any thoughts?
I've tried some variations of Request.QueryString("StartDate") and GridUnapprovedRecords.SelectedRow.FindControl("StartDate"), but I didn't have any luck with those.
The Error:
The parameterized query '(#UserName varchar(13),#EmpID varchar(4),#StartDate varchar(8000' expects the parameter '#StartDate', which was not supplied.
The Sub:
Protected Sub UpdateSelectedRecords_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim cb As CheckBox
Dim atLeastOneRowApproved As Boolean = False
Dim strComment As TextBox
Dim conString As String = ConfigurationManager.ConnectionStrings("MktDataConnectionString").ToString()
Dim sqlConn As New SqlConnection(conString)
sqlConn.Open()
Dim cmd As New SqlCommand(conString,sqlConn)
cmd.Parameters.Add("#UserName", SqlDbType.VarChar)
cmd.Parameters.Add("#EmpID", SqlDbType.VarChar)
cmd.Parameters.Add("#StartDate", SqlDbType.VarChar)
cmd.Parameters.Add("#FileNumber", SqlDbType.VarChar)
cmd.Parameters.Add("#Comment", SqlDbType.VarChar)
' Make changes to dtsp_THS_PerfectAttendanceValidation, row by row
For Each row As GridViewRow In GridUnapprovedRecords.Rows
' Select the current row's check box and comment
cb = CType(row.FindControl("CheckBox1"),CheckBox)
strComment = CType(row.FindControl("Comment"), TextBox)
' Set parameter values for UPDATE statement
cmd.Parameters("#UserName").Value = Row.Page.User.Identity.Name
cmd.Parameters("#EmpID").Value = GridUnapprovedRecords.DataKeys(row.RowIndex).Value
cmd.Parameters("#StartDate").Value = row.Cells(0).Text.ToString()
cmd.Parameters("#FileNumber").Value = row.Cells(2).Text.ToString()
cmd.Parameters("#Comment").Value = row.Cells(5).Text.ToString()
' Determine which UPDATE statement to run
If ((Not (cb) Is Nothing) AndAlso cb.Checked) Then
' Approved records; RecordType left as NULL; Comment Optional
atLeastOneRowApproved = true
If String.IsNullOrEmpty(strComment.Text) Then
' Ignores comment
cmd.CommandText = "UPDATE dtsp_THS_PerfectAttendanceValidation SET UserName = #UserName, ValidationDate = GETDATE() WHERE StartDate = #StartDate AND FileNumber = #FileNumber AND EmpID = #EmpID"
cmd.ExecuteNonQuery()
Else
' Adds Comment
cmd.CommandText = "UPDATE dtsp_THS_PerfectAttendanceValidation SET Comment = #Comment, UserName = #UserName, ValidationDate = GETDATE() WHERE StartDate = #StartDate AND FileNumber = #FileNumber AND EmpID = #EmpID"
cmd.ExecuteNonQuery()
End If
Else
' Unapproved records; Same update except that RecordType is set to "D"; Comment Required
cmd.CommandText = "UPDATE dtsp_THS_PerfectAttendanceValidation SET RecordType = 'D', Comment = #Comment, UserName = #UserName, ValidationDate = GETDATE() WHERE StartDate = #StartDate AND FileNumber = #FileNumber AND EmpID = #EmpID"
cmd.ExecuteNonQuery()
End If
Next
' Reload the page
Response.Redirect(HttpContext.Current.Request.Url.ToString(), True)
End Sub
UPDATE: While Steve provided some great advice, I ended up having to change around the way I was doing things, because I simply COULD NOT get the values to pass from the gridview to VB variables. The only exception was the textbox I was using for Comment, which had to go through multipe steps before I could do anything with it. I tried using row.FindControl("Comment").Text, but that wouldn't work.
strComment = row.FindControl("Comment")
strComment.Text
Lesson learned: Avoid having to get values from the gridview if you can. It might be possible, but it is pretty difficult to do.

If you have a column of type Date for the StartDate field, then do not pass a parameter of type VarChar. This will force the database to execute a conversion following the rules of its installation on the server machine.
You should always pass a parameter with a value appropriate for the type of the receiving column,
So start to declare the parameter as
cmd.Parameters.Add("#StartDate", SqlDbType.Date)
then convert the cell value to a date variable and use that date to set the parameter's value. No conversion required and a date is correctly interpreted by the database engine
Dim start As DateTime
if Not DateTime.TryParse(row.Cells(0).Text, start) Then
' Message about invalid date and return
else
cmd.Parameters("#StartDate").Value = start

SQL statements and stored procedures often include parameters that are evaluated at run time. An SQL statement written with parameters is referred to as a parameterized SQL statement.
When using the SqlDataSource control, you can specify SQL queries and statements that use parameters. This helps make your data-binding scenarios more flexible by reading and writing database information based on values that are evaluated at run time. You can get parameter values from various sources, including ASP.NET application variables, user identities, and user-selected values. You can use parameters to supply search criteria for data retrieval; to supply values to be inserted, updated, or deleted in a data store; and to supply values for sorting, paging, and filtering.
SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = #EmpID"
InsertCommand="INSERT INTO Employees(LastName, FirstName) VALUES (#LastName, #FirstName);
SELECT #EmpID = SCOPE_IDENTITY()"
UpdateCommand="UPDATE Employees SET LastName=#LastName, FirstName=#FirstName
WHERE EmployeeID=#EmployeeID"
DeleteCommand="DELETE Employees WHERE EmployeeID=#EmployeeID"
ConnectionString="<%$ ConnectionStrings:NorthwindConnection %> "OnInserted="EmployeeDetailsSqlDataSource_OnInserted" RunAt="server">
<asp:Parameter Name="EmpID" Type="Int32" DefaultValue="0" />
<asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0"/>
For more details follow https://msdn.microsoft.com/en-us/library/z72eefad.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-3

Related

VB & Access: no value given for one or more required parameters when inserting data

Hello so I have a problem with my simple program that I'm practicing. I'm trying to insert data from vb input box to MS Access database, there are 5 columns in employeeInfo table but the other one is AutoNumber so I didn't include it in the code. The employeeDB has only 3 columns ID, username, pword but I didn't include ID since it's AutoNumber. When I hit the button to add data it will throw an error No value given for one or more required parameters # database_reader = cmd_personal.ExecuteReader even if I did input all the input box that has connection to the database.
Private Sub signUp_btn_Click(sender As Object, e As EventArgs) Handles signUp_btn.Click
Dim usernameInput As String = inputBoxUsername.Text
Dim inputPword As String = inputBoxPword.Text
Dim input_FirstName As String = FirstName_Box.Text
Dim input_MidName As String = MidName_Box.Text
Dim input_LastName As String = LastName_Box.Text
Dim input_ContactNum As String = ContactNumber_Box.Text
dbConnection.Open()
Dim str_personal As String
Dim str_acctInfo As String
str_personal = "INSERT INTO employeeInfo([FirstName], [MiddleName], [LastName], [PhoneNumber]) Values (?, ?, ?, ?)"
str_acctInfo = "INSERT INTO employeeDB([username], [password]) Values (?, ?)"
Dim cmd_personal As OleDbCommand = New OleDbCommand(str_personal, dbConnection)
Dim cmd_acctInfo As OleDbCommand = New OleDbCommand(str_acctInfo, dbConnection)
database_reader = cmd_personal.ExecuteReader
database_reader = cmd_acctInfo.ExecuteReader
database_reader.Read()
' Check If Input box has values
If usernameInput = "" Then
MessageBox.Show("Please Insert Username.")
inputBoxUsername.Clear()
ElseIf inputPword = "" Then
MessageBox.Show("Please Insert Password.")
ElseIf input_FirstName = "" Then
MessageBox.Show("Please insert First Name.")
ElseIf input_MidName = "" Then
MessageBox.Show("Please insert Middle Name.")
ElseIf input_LastName = "" Then
MessageBox.Show("Please insert Last Name.")
ElseIf input_ContactNum = "" Then
MessageBox.Show("Please insert Phone Number.")
End If
' Insert into employeeInfo DB
cmd_personal.Parameters.Add(New OleDbParameter("FirstName", CType(input_FirstName, String)))
cmd_personal.Parameters.Add(New OleDbParameter("MiddleName", CType(input_MidName, String)))
cmd_personal.Parameters.Add(New OleDbParameter("LastName", CType(input_LastName, String)))
cmd_personal.Parameters.Add(New OleDbParameter("PhoneNumber", CType(input_ContactNum, String)))
' Insert into employeeDB acct DB
cmd_acctInfo.Parameters.Add(New OleDbParameter("username", CType(usernameInput, String)))
cmd_acctInfo.Parameters.Add(New OleDbParameter("password", CType(inputPword, String)))
MessageBox.Show("Success! User has been created.")
dbConnection.Close()
I don't need advance solution just a simple one. Thanks!
(I already connect it to the Access Database I just didn't include the code at this post.)
If your SQL contains N ?, then you cannot call cmd_personal.ExecuteReader before you call cmd_personal.Parameters.Add N times to create the parameters (and give them a value)
If your intention is to call the command repeatedly, you can adopt a pattern of:
create command with ? placeholders
add parameters without values, or with representative dummy values if you're using "AddWithValue"/its equivalent (using the paramname,paramvalue constructor, as your code does, is equivalent to calling AddWithValue)
start a loop
set values
execute command
In this case it looks like your code is merely in the wrong order
Ok a few things. There is really no use to write a bunch of separate statements to test if a text box has a value. Like FoxPro, Access, dabase, or just about any system?
They have the ability to "validate" each text box.
So, move that code out. For each control that you want say as required?
So for say FirstName_Box?
Then in the events of the property sheet, use this event:
So, we double click in that Validating event, and we can write this:
Private Sub FirstName_Box_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles FirstName_Box.Validating
If FirstName_Box.Text = "" Then
MsgBox("First name is required")
e.Cancel = True
End If
End Sub
So, now if I click any button on the form, the text box will validate, and also pop up a nice message.
So, now we can dump, and assume our button code will not run until each control and its validation event is ok. It not only saves some code, but what happens if we have 2 or 4 buttons on the form, and now we going to write code to check all those text boxes each time? (nope!!!).
Ok, so now we can assume in our code that any required text box has a value. And if not, then the button click for any button code will not run for us - nice and simple, but more important nice and CLEAN. Since I can now know where to look for any code for a SINGLE control that has some criteria for input.
It also means that you have less code to work with, and deal with at one point in time.
This is much like the answer to this question:
How do you eat a elephant?
Answer: One bite at a time!!!
Ok, now that we have that all fixed up, we can clean up our code to insert.
I actually in a lot of cases suggest using a Datatable, since then we don't have to mess with parameters, but MORE important, it gives us the ability to EASY check if the information or "user" in this case already exists. I mean, you don't want to add the same user two times? Right?
So, now we can clean this up and ALSO check for if the user already exists.
Say somthing like this (warning: air code).
Using conn As New OleDbConnection(My.Settings.AccessDB)
conn.Open()
Dim strSQL As String =
"SELECT * FROM employeeDB WHERE UserName = #User"
Using cmdSQL As New OleDbCommand(strSQL, conn)
Dim da As New OleDbDataAdapter(cmdSQL)
Dim daU As New OleDbCommandBuilder(da)
cmdSQL.Parameters.Add("#User", OleDbType.VarWChar).Value = inputBoxUserName.Text
Dim rstAcctInfo As New DataTable
rstAcctInfo.Load(cmdSQL.ExecuteReader)
If rstAcctInfo.Rows.Count > 0 Then
MsgBox("This user already exists")
return ' bail out and exit
End If
' if we get here, user does not exist, so add this user
Dim OneRow As DataRow = rstAcctInfo.NewRow
OneRow("username") = inputBoxUsername.Text
OneRow("password") = inputBoxPword.Text
rstAcctInfo.Rows.Add(OneRow)
da.Update(rstAcctInfo) ' add this new user
' now add the data to personal
cmdSQL.Parameters.Clear()
cmdSQL.CommandText =
"INSERT INTO employeeInfo([FirstName], [MiddleName], [LastName], [PhoneNumber]) Values " &
"(#FN, #MN,#LN , #Phone)"
With cmdSQL.Parameters
.Add("#FN", OleDbType.VarWChar).Value = FirstName_Box.Text
.Add("#MN", OleDbType.VarWChar).Value = MidName_Box.Text
.Add("#LN", OleDbType.VarWChar).Value = LastName_Box.Text
.Add("#Phone", OleDbType.VarWChar).Value = ContactNumber_Box.Text
End With
cmdSQL.ExecuteNonQuery()
End Using
End Using

How can i resolve ExecucuteNonQuery throwing exception Incorrect syntex near '?'

Dim StrSql = "update student set id=?"
Updated (StrSql,15)
Public Function Updated (ByVal strSql As String, ByVal ParamArray Parameters As String ())
For Each x In Parameters
cmd.Parameters.AddWithValue("?",x)
Next
cmd.ExecuteNonQuery()
End Function
You didn't leave us much to go on; as jmcilhinney points out, you need to add more detail to future questions. For example in this one you have code there that doesn't compile at all, doesnt mention the types of any variable, you don't give the name of the database...
...I'm fairly sure that "Incorrect syntax near" is a SQL Server thing, in which case you need to remember that it (re)uses named parameters, unlike e.g. Access which uses positional ones:
SQL Server:
strSql = "SELECT * FROM person WHERE firstname = #name OR lastname = #name"
...Parameters.AddWithValue("#name", "Lee")
Access:
strSql = "SELECT * FROM person WHERE firstname = ? OR lastname = ?"
...Parameters.AddWithValue("anythingdoesntmatterwillbeignored", "Lee")
...Parameters.AddWithValue("anythingdoesntmatterwillbeignoredalso", "Lee")
This does mean your function will need to get a bit more intelligent; perhaps pass a ParamArray of KeyValuePair(Of String, Object)
Or perhaps you should stop doing this way right now, and switch to using Dapper. Dapper takes your query, applies your parameters and returns you objects if you ask for them:
Using connection as New SqlConnection(...)
Dim p as List(Of Person) = Await connection.QueryAsync(Of Person)( _
"SELECT * FROM person WHERE name = #name", _
New With { .name = "John" } _
)
' use your list of Person objects
End Using
Yep, all that adding parameters BS, and executing the reader, and converting the results to a Person.. Dapper does it all. Nonquery are done like connection.ExecuteAsync("UPDATE person SET name=#n, age=#a WHERE id=#id", New With{ .n="john", .a=27, .id=123 })
http://dapper-tutorial.net
Please turn on Option Strict. This is a 2 part process. First for the current project - In Solution Explorer double click My Project. Choose Compile on the left. In the Option Strict drop-down select ON. Second for future projects - Go to the Tools Menu -> Options -> Projects and Solutions -> VB Defaults. In the Option Strict drop-down select ON. This will save you from bugs at runtime.
Updated(StrSql, 15)
Your Updated Function calls for a String array. 15 is not a string array.
Functions need a datatype for the return.
cmd.Parameters.AddWithValue("?", X)
cmd is not declared.
You can't possible get the error you mention with the above code. It will not even compile, let alone run and produce an error.
It is not very helpful to write a Function that is trying to be generic but is actually very limited.
Let us start with your Update statement.
Dim StrSql = "update student set id=?"
The statement you provided will update every id in the student table to 15. Is that what you intended to do? ID fields are rarely changed. They are meant to uniquely identify a record. Often, they are auto-number fields. An Update command would use an ID field to identify which record to update.
Don't use .AddWithValue. See http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
Here is another
https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html
Since you didn't tell us what database you are using I guessed it was Access because of the question mark. If it is another database change the connection, command and dbType types.
Using...End Using block ensures you connection and command are closed and disposed even if there is an error.
Private ConStr As String = "Your Connection String"
Public Function Updated(StudentNickname As String, StudentID As Integer) As Integer
Dim RetVal As Integer
Using cn As New OleDbConnection(ConStr),
cmd As New OleDbCommand("Update student set NickName = #NickName Where StudentID = #ID", cn)
cmd.Parameters.Add("#NickName", OleDbType.VarChar, 100).Value = StudentNickname
cmd.Parameters.Add("#ID", OleDbType.Integer).Value = StudentID
cn.Open()
RetVal = cmd.ExecuteNonQuery
End Using
Return RetVal
End Function
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim RowsUpdated = Updated("Jim", 15)
Dim message As String
If RowsUpdated = 1 Then
message = "Success"
Else
message = "Failure"
End If
MessageBox.Show(message)
End Sub
This code keeps your database code separated from user interface code.

vb.net DatePicker not setting value when new date is selected

I'm working on a vb.net application (I'm very new to vb.net), and have just added a DatePicker to a field on a form- PostDate (the field was previously just a text box).
The date picker appears to work visually- when the user clicks inside the form field, the date picker calendar appears, and they can select a date from the current month, or switch months to select a date from another month. Once the user has selected a date, the calendar disappears, and the newly selected date is displayed in the field in the format mm/dd/yyyy.
However, while debugging my application, when I reach the UpdateButton_Click() function that is handling the updates to fields in the form (i.e. checking to see if any of their values have changed, and updating them in the database if they have), I see that in the line I have added to check for changes to the date field that I have just added the DatePicker to, the date variable still holds the previous value (i.e. the original date, rather than the newly selected date).
The UpdateButton_Click() function is defined with:
Protected Sub UpdateButton_Click(sender As Object, e As EventArgs) Handles UpdateButton.Click
If Page.IsPostBack Then
...
Dim mypostdate As String = HttpUtility.HtmlEncode(PostDate.Text & " " & theTime.Text)
...
C.updateCaseByCaseID(... mypostdate, ...)
...
Next
End If
End Sub
If I put a break point on this function, and step through it, I can see that the value of PostDate.Text is always its original value (i.e. it has a previously saved value when the page loads). Even if I change the value of the field to a new date, using the date picker, although the field shows the new date in the browser, when I step through this function, the value of PostDate.Text is always the original date value.
The call to C.updateCaseByCaseID(...) appears to be what is handling the database updates, and was originally defined in cases.vb with:
Public Function updateCaseByCaseID(ByVal Caseid As String, ...) As String
Dim con As New SqlConnection(connectionString)
Dim sql As String = "UPDATE tableName SET "
sql = sql & " ReportNumber=#ReportNumber, ... "
If status = "" Then
Else
sql = sql & " ,status=status "
End If
...
If PostDate = "" Then
Else
sql = sql & ", PostDate=#PostDate"
End If
' Other similar If Else statements for the other parameters '
...
Dim cmd As New SqlCommand(sql, con)
cmd.Parameters.AddWithValue("#CID", Cid)
...
cmd.Parameters.AddWithValue("#PostDate", PostDate)
' Other similar AddWithValue statements '
...
If state = "" Then
Else
cmd.Parameters.AddWithValue("#State", State)
End If
' Other similar If statements for the other parameters '
...
con.Open()
cmd.ExecuteNonQuery()
con.Close()
Dim myaction As String = "Done"
Return myaction
End Function
I added the postdate parameter to the sql variable by changing that line to:
sql = sql & " ReportNumber=#ReportNumber, ..., PostDate=#PostDate, ...
However, although this does now update the value of the post date field, it appears to update it to today's date, rather than the date selected by the DatePicker. This seems to be because although the PostDate field displays the newly selected date in the browser, in the UpdateButton_Click(...) function, in the line
Dim mypostDate As String = HttpUtility.HtmlEncode(PostDate.Text + " " + theTime.Text)
the variable PostDate.Text, i.e. the form field that is displaying the newly selected date in the browser, appears to have the value of today's date... I don't understand why this is happening...? Surely it should contain the value of the date selected in the DatePicker? Especially given that that is what's being displayed in the browser...
Anyone have any suggestions what I'm doing wrong with this?
Edit
As mentioned in the comments, I have updated the UpdateButton_Click() function as follows:
Protected Sub UpdateButton_Click(sender As Object, e As EventArgs) Hanles UpdateButton.Click
If Page.IsPostBack Then
...
Dim mypostdate As String = HttpUtility.HtmlEncode(PostDateTxt.Text & " " & theTime.Text)
Dim postDateAndTimeParts = mypostdate.Split("/")
Dim postTime = postDateAndTimeParts(2).Split("/")
Dim postDay = postDateAndTimeParts(1)
Dim postMonth = postDateAndTimeParts(0)
Dim postYear = postDateAndTimeParts(2).Split(" ")(0)
Dim postHour = postTime.Split(":")(0)
Dim postMin = PostTime.Split(":")(1)
DateTime PostDate = New DateTime(postYear, postMonth, postDay, postHour, postMin, 0);
...
C.updateCaseByCaseID(...)
End If
End Sub
My intention is to pass the new PostDate DateTime object that I'm reconstructing from the String into the C.updateCaseByCaseId(...) call, however on the line where I'm constructing that object, I'm currently getting a compile error that says:
Method arguments must be enclosed in parentheses
I'm not sure why this is? I can't see where I'm missing any parentheses...

Parameterized SQL UPDATE Statement

I have seen many examples of the parameterized SQL queries, but have run into a few questions.
I know I am not hashing passwords, so please disregard that.
The following is my code:
cmd.CommandText = "UPDATE users SET username=#uName, pwd=#pWord, role=#uRole, actuser=#uActive WHERE ID=" & recordID
cmd.Parameters.AddWithValue("#uName", tbUsername.Text)
cmd.Parameters.AddWithValue("#pWord", tbPassword1.Text)
cmd.Parameters.AddWithValue("#uRole", cbRole.SelectedItem)
cmd.Parameters.AddWithValue("#uActive", isActive)
The error I get is:
"Data type mismatch in criteria expression"
I don't understand why because everything in the database is "Short String" except for "actuser" which is set to Yes/No and "isActive" is set to "Yes" when the code attempts to run. I have validated the table column headers to be accurate and I don't know why this is not working.
This format seems to work with an INSERT statement, but not an UPDATE statement... but I can't confirm that right at this moment.
Any help would be appreciated.
EDIT:
Updated code with same error.
Dim isActive As Boolean = False
If cbxActive.CheckState = CheckState.Checked Then
isActive = "True"
End If
cmd.CommandText = "UPDATE users SET username=#uName, pwd=#pWord, role=#uRole, actuser=#uActive WHERE ID=#ID"
cmd.Parameters.AddWithValue("#uName", tbUsername.Text)
cmd.Parameters.AddWithValue("#pWord", tbPassword1.Text)
cmd.Parameters.AddWithValue("#uRole", cbRole.SelectedItem.ToString())
cmd.Parameters.AddWithValue("#uActive", If(isActive, "Yes", "No"))
cmd.Parameters.AddWithValue("#ID", recordID)
myConnection.Open()
Try
cmd.ExecuteNonQuery()
Catch ex As OleDb.OleDbException
MsgBox(ex.Message)
Exit Sub
End Try`
SelectedItem is returning a string from a collection in a combobox.
Here is my DB structure.Link to Picture of Access DB structure
Here is the other structure pic. enter image description here
Of course, we can only guess what is in isActive and cbRole.SelectedItem but we know for sure that one of these if not both, causing your issue.
Specifically, you can use AddWithValue only when direct match type is used. otherwise you need to precisely set parameter data type like this
Dim p As New OleDbParameter(#pName, OleDbType.SomeType)
p.Value = [your value]
cmd.Parameters.Add(p)
In your case these 2 lines could be [scratch that] are! problematic
cmd.Parameters.AddWithValue("#uRole", cbRole.SelectedItem)
cmd.Parameters.AddWithValue("#uActive", isActive)
first line returns object that can be anything (only you know). What to do with it
' If selected item is string
cmd.Parameters.AddWithValue("#uRole", cbRole.SelectedItem.ToString())
' If selected item is integer
cmd.Parameters.AddWithValue("#uRole", CInt(cbRole.SelectedItem))
' If selected item is complex object in which you use property
Dim val As Integer = DirectCast(cbRole.SelectedItem, MyObjectType).SomeIntProperty
cmd.Parameters.AddWithValue("#uRole", val)
' If your value 'isActive' is boolean and you keep Yes/No in DB, you need this
cmd.Parameters.AddWithValue("#uActive", if(isActive, "Yes", "No"))
' and opposite
cmd.Parameters.AddWithValue("#uActive", if(isActive = "Yes", 1, 0))
' you have to be careful here. In .NET false=0, all else <> 0. so, if your business logic needs True=1, all else <> 1, you need to convert correspondingly
And last thing - why not parameterize ...WHERE ID=" & recordID...? do exactly same thing
cmd.CommandText = ". . . . . WHERE ID= #id"
cmd.Parameters.AddWithValue("#id", recordID)

Data type mismatch when inserting record

I've this piece of code for inserting records into an Access table.
LastUpdated field is defined as Date/Time at database level. It fails when inserting giving the error
Data type mismatch in criteria expression
I'm using parameterized query which avoid problems with formatting values and it's very weird because I've the same code (with more parameters) to insert records on another table on which LastUpdated is defined in the same way and it's working fine.
Any idea?
SqlQuery = "INSERT INTO History (ActivityID, LastUpdated) VALUES (#p1,#p2)"
With sqlcommand
.CommandText = SqlQuery
.Connection = SQLConnection
.Parameters.AddWithValue("#p1", IDAct)
.Parameters.AddWithValue("#p2", DateTime.Today)
End With
result = sqlcommand.ExecuteNonQuery()
If (result = 1) Then
LabelWarning.Text = "Activity filled"
LabelWarning.BackColor = Color.ForestGreen
LabelWarning.Visible = True
ButtonSave.Visible = False
ButtonBack.Visible = False
ButtonOK.Visible = True
BlockControls()
End If
Maybe the problem is linked to parameter placeholder.
This MSDN doc states that OleDbCommand does not support named parameter (only positional) and the correct placeholder should be "?" and not "#p1".
https://msdn.microsoft.com/en-us/library/yy6y35y8%28v=vs.110%29.aspx
Edit
It turned out in comments that the placeholder have not to be so strictly adherent to the doc syntax. Only the order has to be absolutely preserved.
Explicitly declaring the parameter type however seemed to do the trick:
.Parameters.Add("#p2", OleDbType.DBTimeStamp)
.Parameters("#p2").Value = DateTime.Today