I am trying to make a banking system where the customer will only be able to deposit money IF ONLY they enter the CORRECT AccountNo & Name using Microsoft Access Databse in VB NET.
Here are my codes:
Dim conn As New OleDbConnection
Dim conn = "provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\Database\Bank-Application-Database.accdb;"
conn.ConnectionString = "provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\Database\Bank-Application-Database.accdb;"
cmdupdate.Connection = cnnOLEDB
Dim deposit As OleDbCommand = New OleDbCommand("SELECT * FROM [Current_Account] WHERE [AccountNo] and [CustomerName] = '" & accnotxt.Text & "' AND [CustomerName] = '" & nametxt.Text & "' AND [Amount] = '" & amounttxt.Text & "'", myConnection)
deposit.Connection = conn
conn.Open()
If accnotxt.ToString = True And nametxt.ToString = True Then
cmdupdate.CommandText = "UPDATE [Current_Account] SET [Amount] = '" & amounttxt.Text.ToString & " WHERE [AccountNo] AND [CustomerName] = " & accnotxt.Text.ToString & " " & nametxt.ToString & ";"
cmdupdate.CommandType = CommandType.Text
cmdupdate.ExecuteNonQuery()
MsgBox(" Successfully deposited.")
Else
MsgBox("Incorrect Account Number or Name.")
I am able to run.However when I click to Deposit, this is the error.
The error I got:
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "System.Windows.Forms.TextBox, Te" to type 'Boolean' is not valid.
Any helpers ? Thanks in advance.
In addition to #Jonathon Ogden's answer:
You missed your single quotes in this query:
cmdupdate.CommandText = "UPDATE [Current_Account] SET [Amount] = '" & amounttxt.Text.ToString & " WHERE [AccountNo] AND [CustomerName] = " & accnotxt.Text.ToString & " " & nametxt.ToString & ";"
Change it to this:
cmdupdate.CommandText = "UPDATE [Current_Account] SET [Amount] = " & Val(amounttxt.Text) & " WHERE [AccountNo]= '" & accnotxt.Text & "' AND [CustomerName] = '" & nametxt.Text & "';"
I also removed there the single quote from amounttxt.Text.ToString assuming it's a value, changed it to Val(amounttxt.Text) so that even that textbox is blank, it won't cause an error.
Also corrected your WHERE Condition:
Another is you don't need .ToString anymore since .Text property is already a String.
Your ToString usage will convert the value of the accnotxt and nametxt text boxes into a text string and you're trying to compare that to True (i.e. accnotxt.ToString = True) which is of a Boolean data type not a String data type i.e. you are trying to compare text to a boolean (true or false) value.
A very basic way (that can be improved on) of doing the account number and name check would be to change your SELECT statement to:
Dim deposit As OleDbCommand = New OleDbCommand("SELECT * FROM [Current_Account] WHERE [AccountNo] and [CustomerName] = '" & accnotxt.Text & "' AND [CustomerName] = '" & nametxt.Text & "'", myConnection)
I removed the Amount filter from the WHERE clause as I am not sure why you are doing that. You don't even use this deposit database command. You then execute the deposit SQL command and get its result: Dim result = deposit.ExecuteScalar(). ExecuteScalar does the following:
Executes the query, and returns the first column of the first row in the result set returned by the query.
You then change your account number and name check to If result IsNot Nothing Then instead of checking if the values of the textboxes are a particular account number and name.
In other words, if your query returns something and not nothing, then you can assume a current account exists with the accnotxt and nametxt.
Also, pay attention to #CrushSundae answer as they have highlighted other issues too.
Related
I am trying to update access table using simple VBA code, however it finished with an error. I have tried various ways to solve it but without success.
Could you please help? The code is as follow:
strSQL = "UPDATE Projects " & _
"SET Projects.id_status = '" & Me.T_project_s.Value & "' " & _
"WHERE Projects.id_project = '" & Me.curr_open.Value & "';"
I have also tried:
strSQL = "UPDATE Projects " & _
"SET Projects.id_status = [" & Me.T_project_s.Value & "] " & _
"WHERE Projects.id_project = [" & Me.curr_open.Value & "];"
or
strSQL = "UPDATE [Projects] " & _
"SET [Projects].[id_status] = '" & Me.T_project_s.Value & "' " & _
"WHERE [Projects].[id_project] = '" & Me.curr_open.Value & "';"
But it asks for a data which is available in those fields.
Your suggestion helped. I started with only a text then I have changed particular variables I wanted to be read. So in the Where statement there is no need to have beside "" also '' :).
strSQL = "UPDATE [Projects] " & _
"SET [Projects].[id_status] = '" & Me.T_project_s.Value & "' " & _
"WHERE [Projects].[id_project] = " & Me.curr_open.Value & ";"
Thanks.
Once again, here is an example where parameterization (an industry best practice in SQL programming) helps beyond avoiding SQL injection. With querydef parameters you:
avoid the need of quote enclosure;
avoid string interpolation of variables;
abstract data (i.e., VBA variables) from code (i.e., SQL statement) for cleaner scripts;
(plus as OP found out with mixed types) explicitly define the data types of values to be binded;
execute the query via DAO for smoother user interface than DoCmd.RunSQL that raises warnings to users.
Temp Query
Dim qdef As QueryDef
' PREPARED STATEMENT, DEFINING PLACEHOLDERS (NO DATA)
strSQL = "PARAMETERS [project_s_param] Text(255), [curr_open_param] Long;" & _
" UPDATE [Projects]" & _
" SET [Projects].[id_status] = [project_s_param]" & _
" WHERE [Projects].[id_project] = [curr_open_param];"
' CREATE UNNAMED TEMP QUERYDEF, ASSIGNING PREPARED STATEMENT
Set qdef = CurrentDb.CreateQueryDef("", strSQL)
' BIND VBA VALUES TO PARAMETER PLACEHOLDERS
qdef![project_s_param] = Me.T_project_s.Value
qdef![curr_open_param] = Me.curr_open.Value
' EXECUTE ACTION
qdef.Execute dbFailOnError
Set qdef = Nothing
Saved Query
Even better, save entire prepared statement as a stored Access query and avoid any SQL in VBA.
SQL (save as any regular query object whose name is referenced in VBA)
PARAMETERS [project_s_param] Text(255), [curr_open_param] Long;
UPDATE [Projects]
SET [Projects].[id_status] = [project_s_param]
WHERE [Projects].[id_project] = [curr_open_param]
VBA
Dim qdef As QueryDef
' REFERENCE EXISTING QUERYDEF, ASSIGNING PREPARED STATEMENT
Set qdef = CurrentDb.QueryDefs("mySavedQuery")
' BIND VBA VALUES TO PARAMETER PLACEHOLDERS
qdef![project_s_param] = Me.T_project_s.Value
qdef![curr_open_param] = Me.curr_open.Value
' EXECUTE ACTION
qdef.Execute dbFailOnError
Set qdef = Nothing
I want some sort of label that is counting every record that is imported in the database.
Do I need to use a for each loop?
Can someone explain me how to do it, or set me on the right way to do it?
With cmd
.CommandText = "INSERT INTO Workflow ([Import], [DossierPad]) VALUES ('" + Import + "','" + Pad + "')"
.ExecuteNonQuery()
.CommandText = "INSERT INTO Data ([DossierPad], [Tif], [Grootte]) VALUES ('" + Pad + "','" + stukjes(0) + "','" + stukjes(2) + "')"
.ExecuteNonQuery()
If Tifcheck(Tif) = False Then
cmd.CommandText = "Update Data Set Tif = '" & Tif & "' WHERE Tif="
ElseIf Tifcheck(Tif) = True Then
End If
If stukjes(2) < 20000 Then
.CommandText = "UPDATE Data SET Blanco = '" & blanco & "' WHERE DossierPad = '" & Pad & "'"
.ExecuteNonQuery()
Else
.CommandText = "UPDATE Data SET Blanco = '" & blanco1 & "' WHERE DossierPad = '" & Pad & "'"
.ExecuteNonQuery()
End If
End With
This is the part of code where I insert records in my database.
Now my question is how can I get a label to count every record in the database while it is intering.
As specified in the MSDN docs, the method ExecuteNonQuery() returns the number of rows affected by your query. This is often used to check that your insert query ended up correctly.
So what you can do is declare an Integer somewhere in your code, and increment this integer with the result of the ExecuteNonQuery() method call.
At the end, you can update a Label with the value of your integer.
Some code:
'At the beginning of your update function
Dim myCounter As Integer
'...
'Whenever you run ExecuteNonQuery() on an INSERT statement
myCounter += .ExecuteNonQuery()
'...
'Finally, on the label that should display the result
myLabel.Text = "Updated " & myCounter.toString() & " rows."
My code is now this, as i forgot to add the connection to my database after i updated the table, still doesnt work though
Private Sub cmdRegistar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRegistar.Click
myConnToAccess = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source = 'D:\PAP\LoginForm\LoginForm\bin\debug\login.mdb'")
myConnToAccess.Open()
Try
Dim x As String
Dim str As String
x = ComboBox1.Text
str = "UPDATE UserTable set Password = '" & txtPass.Text & "' where Username = '" & x & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnToAccess)
myConnToAccess.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
So as you can see the code doesnt have any errors, it compiles and runs just fine, it just doesnt work, the combobox values come from the same database of what i'm trying to do with the command update. All my others conections work just fine, my add, search.
When are you actually passing str to your database? Shouldn't you have something like str.Execute or something in there? Aside from that, you also have an error in this line:
str = "UPDATE UserTable set Password" & txtPass.text & "where Username= '" & x & "'"
It should be:
str = "UPDATE UserTable set Password = '" & txtPass.text & "' where Username = '" & x & "'"
Password is a reserved word, so try this:
str = "UPDATE UserTable set [Password] = '" & txtPass.Text & "' where Username = '" & x & "'"
I am trying to do a simple insert or update into SQL Server as NULL, not blank. I have seen many references online to just set Field = NULL without quotes but it is still coming up as empty, not NULL. Incredibly frustrating.
This is in classic asp.
If Request.Form("Field") = "" or IsNull(Request.Form("Field")) then
Field = NULL
Else
Field = Request.Form("Field")
End If
sSql="UPDATE [table] SET timestamp = {fn NOW()}," &_
"Field = '" & Field & "'," &_
"WHERE [System] = '" & System & "' and Active = '1'"
If I do this, it proves that it is checking because it puts in a 1.
If Request.Form("Field") = "" or IsNull(Request.Form("Field")) then
Field = 1
Else
Field = Request.Form("Field")
End If
sSql="UPDATE [table] SET timestamp = {fn NOW()}," &_
"Field = '" & Field & "'," &_
"WHERE [System] = '" & System & "' and Active = '1'"
I tried this but get an error 500:
sSql="UPDATE [Table] SET timestamp = {fn NOW()}, Field = "
If IsNull(Field) Then
sSQL = sSQL & "NULL"
Else
sSQL = sSQL & "'" & Field & "'" &_
End If
"NTLogon = '" & UCase(NTLogon) & "'" &_
"WHERE [System] = '" & System & "' and Active = '1'"
When I try this in place of my original code:
Field Assignment:
Field = "NULL" and Field = "'" & Request.Form("Field") & "'"
sSQL:
"Field = " & Field & "," &_
I get "An error occurred on the server when processing the URL."
So yeah, insert rant here about using parameterized queries, blah blah blah... now that's out of everyone's system, could we maybe look at the actual question?
The problem is this:
"Field = '" & Field & "'"
Those ampersands are converting your lovingly-populated vbScript NULL value right back into a string. If you don't want that to happen, you need to explicitly handle the IsNull case.
sSQL = "UPDATE [table] SET timestamp = {fn NOW()}, Field = "
If IsNull(Field) Then
sSQL = sSQL & "NULL"
Else
sSQL = sSQL & "'" & Field & "'"
End If
sSQL = sSQL & " WHERE [System] = '" & System & "' AND Active = '1'"
Note that even if you do this via a parameterized query, you'll need to make sure you're not appending your vbScript NULL value onto a string, because "" & NULL = "".
#pinchetpooche Hello there. I had the same issue and tried the given answer, and also received a 500 error page. I found that #Martha forgot to include the necessary SQL field that is being updated (i.e., "Field"). So I put together some test code, using her solution (i.e., using string concatenation and conditional logic), and executed against an actual database, and this solution works perfectly:
sSQLNullTest = "UPDATE CustomersToCCData SET "
sSQLNullTest = sSQLNullTest & "CustomerID = " & iCustomerID & ", "
If IsNull(x_license_number_state) Or x_license_number_state = "" Then
sSQLNullTest = sSQLNullTest & "CCLicenseState = NULL"
Else
sSQLNullTest = sSQLNullTest & "CCLicenseState = '" & x_license_number_state & "' "
End If
sSQLNullTest = sSQLNullTest & " WHERE CCID = '" & iCCInfoCCID & "'
In the below code, my second query will not insert into the SQL database, but the first one will update. I can copy the query (from the msgbox i added for testing) and paste it in SQL Server Management Studio, and it will execute fine. I also do not get any error messages back from SQL, though i'm not sure if that code is correct (it was copied + pasted from another source). Also, can i simplify the code to pass both queries at the same time?
Dim Conn As New System.Data.SqlClient.SqlConnection 'sql server datastream connection
Dim Cmd As New System.Data.SqlClient.SqlCommand 'sql command vars
Dim SqlQuery As String 'string var used to hold various SQL queries
Dim data As System.Data.SqlClient.SqlDataReader 'datareader object variable
Dim MVDataset As New DataSet
Dim MVDatatable As DataTable
Dim MVDatarow As DataRow
Private Sub MVUpdateButton_Click(sender As Object, e As EventArgs) Handles MVUpdateButton.Click
vbyn = MsgBox("Are you sure you want to update Tally Sheet Master Variables?" & vbCrLf & vbCrLf & "Changes to these variables will change the functionality of the Tally Sheet!", vbYesNo, )
Try
Select Case vbyn
Case vbNo
GoTo MVTableUpdateBypass
Case vbYes
'get new data from textboxes
Vers = TextBox1.Text
If TextBox2.Text = True Then
Testing = 1
Else
Testing = 0
End If
FlatFeeCharge = TextBox3.Text
PrepricingCharge = TextBox4.Text
SendMailAcct = TextBox5.Text
SendMailPW = TextBox6.Text
TestingEmail = TextBox7.Text
PrePricingEmail = TextBox8.Text
ImperataEmail = TextBox9.Text
'update existing active row to mark inactive
SqlQuery = "Update MasterVars set Active = 0 where PKEY = " & PKEY & ";"
MsgBox(SqlQuery)
If Conn.State = ConnectionState.Closed Then
Conn.ConnectionString = "Data Source=SQL01;Initial Catalog=TallySheet;Integrated Security=SSPI;"
End If
Conn.Open()
Dim MVDataAdapter As New SqlDataAdapter(SqlQuery, Conn)
Dim MVUpdateCommand As SqlCommand
MVUpdateCommand = New SqlCommand(SqlQuery)
MVDataAdapter.UpdateCommand = MVUpdateCommand
'insert new active row
SqlQuery = "Insert into MasterVars (Vers, Testing, FlatFeeCharge, PrePricingCharge, SendMailAcct, SendMailPW, TestingEmail, PrePricingEmail, ImperataEmail, DTS, UserName, Active) Values (" & "'" & Vers & "', " & Testing & ", '" & FlatFeeCharge & "'" & ", '" & PrepricingCharge & "'" & ", '" & SendMailAcct & "'" & ", '" & SendMailPW & "'" & ", '" & TestingEmail & "'" & ", '" & PrePricingEmail & "'" & ", '" & ImperataEmail & "'" & ", '" & Date.Now & "'," & "'QGDOMAIN\" & Environment.UserName & "'," & 1 & ");"
MsgBox(SqlQuery)
Dim MVInsertCommand As SqlCommand
MVInsertCommand = New SqlCommand(SqlQuery)
MVDataAdapter.InsertCommand = MVInsertCommand
MVDataAdapter.Fill(MVDataset, "MasterVars")
End Select
Catch ex As SqlException
Dim i As Integer
Dim errormessages As String
errormessages = ""
For i = 0 To ex.Errors.Count - 1
errormessages = errormessages & " " & ("Index #" & i.ToString() & ControlChars.NewLine _
& "Message: " & ex.Errors(i).Message & ControlChars.NewLine _
& "LineNumber: " & ex.Errors(i).LineNumber & ControlChars.NewLine _
& "Source: " & ex.Errors(i).Source & ControlChars.NewLine _
& "Procedure: " & ex.Errors(i).Procedure & ControlChars.NewLine)
Next i
Console.WriteLine(errorMessages.ToString())
End Try
'reload form with updated variables
Conn.Close()
Conn.Dispose()
MVTableUpdateBypass:
End Sub
The Fill method of the SqlDataAdapter executes the SelectCommand not the UpdateCommand or the InsertCommand. In any case these two commands (and the DeleteCommand) are executed when you call the Update method of the adapter.
Moreover the Update method runs the commands looking for rows changed/added/deleted in the DataTable/DataSet retrieved by the SelectCommand and works only for those rows.
But you don't need an SqlDataAdapter to execute your two queries. You should simply construct an SqlCommand with both texts separated by a semicolon and call ExecuteNonQuery
SqlQuery = "Update MasterVars set Active = 0 where PKEY = #key;" & _
"Insert into MasterVars (Vers, Testing, .....) VALUES (#p1, #o2, ....)"
Using Conn = New SqlConnection("Data Source=SQL01;......")
Using cmd = New SqlCommand(SqlQuery, Conn)
Conn.Open()
cmd.Parameters.Add("#key", SqlDbType.Int).Value = PKEY
cmd.Parameters.Add("#p1", SqlDbType.NVarChar).Value = vers
cmd.Parameters.Add("#p2", SqlDbType.Int).Value = testing
... and so on with other parameters ....
cmd.ExecuteNonQuery()
End Using
End Using
In this incomplete example (too many parameters to write down) I have concatenated the two sql texts in a single string and prepared it with parameter placeholders. Then I build the parameter collection with the exact datatypes required by your table and finally call ExecuteNonQuery to run everything on the database side.
Notice that is not needed to keep global objects like the connection or the command. It is always better to create a local variable, use and destroy it when done. In particular disposable objects like the connection and the command should always created in a Using block