This is the first time I run any type of queries and/or connect to a database through vb. I have looked up my problem on line but have not found exactly what I am looking for.
I have a simple login page on my windows application that runs out of a compact .sdf database. I need to add a procedure that allows the user to change the password.
If the user name in textbox1 and the password in textbox2 match what I have stored in my database, then replace the password with the values of textbox3.
So far I have been able to figure out how to create a new account and verify the log in. I log in using the following:
SELECT username, userpassword
FROM UserInfo
WHERE (username LIKE #username) AND (userpassword LIKE #userpassword)
Then the procedure on my button:
' Check if username or password is empty
If txtPassword.Text = "" Or txtUserName.Text = "" Then
MessageBox.Show("Please complete the required fields..", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
'Clear all fields
txtPassword.Text = ""
txtUserName.Text = ""
'Focus on Username field
txtUserName.Focus()
Else
'If the password and username match, open the main form.
If Not UserInfoTableAdapter1.Login(txtUserName.Text, txtPassword.Text) = Nothing Then
Dim frmWelcome As New frmWelcomePage
frmWelcome.Show()
Me.Hide()
Else
MessageBox.Show("You have entered an invalid user name or password", "Invalid Login", MessageBoxButtons.OK, MessageBoxIcon.Error)
'Clear all fields
txtPassword.Text = ""
txtUserName.Text = ""
'Focus on Username field
txtUserName.Focus()
End If
End If
How can I use something similar to change the password?
As #pickypg said you should definitely look for an exact match with passwords and usernames. Also you should consider a one way hash for user passwords. This answer does a good job of describing the potential danger of storing plain text passwords. This article has related information and is also amusing.
That aside the sql you're looking for might be something like this:
create procedure updateUserPassword
#userName varchar(max)
,#oldHashedPassword nvarchar(128)
,#newHashedPassword nvarchar(128)
as
begin
set nocount on;
if exists ( select 1 from UserInfo where username = #userName and userpassword = #oldHashedPassword )
begin
update UserInfo set userPassword = #newHashedPassword where username = #userName;
end
else
begin
raiserror('No record found for user', 16, 1);
end
end
Related
ConnectString.connectStr()
con.Open()
Try
cmd.Connection = con
cmd.CommandText = ("select COUNT(userid) from login where userid='" & UserNametxt.Text & "'")
Dim userName As Integer = Convert.ToInt32(cmd.ExecuteScalar())
If userName <> 0 Then
cmd.CommandText = ("select COUNT(password) from login where userid='" & passwordtxt.Text & "'")
Dim password As Integer = Convert.ToInt32(cmd.ExecuteScalar())
If password <> 0 Then
UserMenu.Show()
Else
MsgBox("Password is wrong")
End If
Else
Query result of normal Query and Function could not be different for your case. But there should be a problem in your function.
Please correct your code with below one.
CREATE FUNCTION test_example (#userid BIGINT)
RETURNS BIGINT
BEGIN
RETURN (select COUNT(userid) from login where userid = #userid)
END
Keep your connection local and don't open it until the last minute.
The Using blocks ensure that your database objects will be closed and disposed even if there is an error.
Always use parameters when calling the database. Otherwise you risk Sql Injection. Also it prevents errors passing the data and may speed up the query.
Why hit the database twice? Just ask you question in one query with an And in the Where clause. Don't let the user know if the username or password is incorrect. Remember, you are trying to prevent unauthorized access. Just say that the login failed.
I moved the declaration of CountUser above the Using block so it can be seen below the Using block. We don't want to display the MessageBox while the connection is open. There is no telling when the user would respond to the message and the connection would be open waiting.
In a real application you would never store passwords as plain text.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim CountUser As Integer
'Pass the connection string directly to the constructor of the connection.
Using cn As New SqlConnection("Your connection string")
'Pass the command text and the connection directly to the constructor of the command
Using cmd As New SqlCommand("select COUNT(userid) from login where userid = #UserID And password = #password;", cn)
'I am guessing on the SqlDbType. Check the database for the actual type.
cmd.Parameters.Add("#UserID", SqlDbType.VarChar).Value = UserNametxt.Text
cmd.Parameters.Add("#password", SqlDbType.VarChar).Value = passwordtxt.Text
cn.Open()
CountUser = Convert.ToInt32(cmd.ExecuteScalar())
End Using
End Using
If CountUser <> 1 Then
MessageBox.Show("Login Failed")
Else
'Send them into the progam
End If
End Sub
I'm sorry if the title is a little vague but I wasn't sure how to put it in a short space.
For context, I have a save button, which is when changes made are updated in the SQL server database. This works fine when adding rows, or changing values, even deleting rows. Nothing wrong there.
However, when I try to add or remove columns the app becomes a bit more problematic and simply does not update added/removed columns in the database and doesnt throw an error.
The only way I can get adding or removing columns to work is to use a sql query on the add/delete buttons, but this saves directly to the server - which i do not want.
What I need is for the changes to appear in the table, and then only update the database when the save button is clicked.
My code is here --- (Note, this is done over three forms, I have the main form with the table, plus two more that are used for inputting the name of the "trainer column" that is to be added or removed)
Private Function save() ''''' Main form
Try
ds.Tables(0).AcceptChanges()
da.Update(ds)
DataTableColours()
MessageBox.Show("Data updated successfully.")
Catch
MessageBox.Show("Data failed to update properly. Please ensure you are connected to the Baltic network and try again. If the problem persists, seek IT support.")
End Try
End Function
Public Function AddTrainerFunc() ''''' Main form
'Dim SqlAddCol As String = "ALTER TABLE MasterTrainerSchedule ADD [" & TrainerName.Trim() & "] nvarchar(255)"
'Using con As New OleDbConnection(cs)
' Using cmd As New OleDbCommand(SqlAddCol, con)
' con.Open()
' cmd.ExecuteNonQuery()
' End Using
'End Using
ds.Tables(0).Columns.Add(TrainerName.Trim()).DefaultValue = " "
RefreshBtn()
End Function
Public Function delTrainerFunc() ''''' Main form
Dim SqlDelCol As String = "ALTER TABLE MasterTrainerSchedule DROP COLUMN [" & TrainerName.Trim() & "]"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlDelCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
ds.Tables(0).Columns.Remove(TrainerName)
DelTrainer.Close()
RefreshBtn()
MessageBox.Show("Trainer '" & TrainerName.Trim() & "' has been deleted from the table.")
End Function
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click '''''Add Column Form
If Not txtTrainerName.Text = "Trainer Name Here" Or txtTrainerName.Text = "" Then
MTS.TrainerName = txtTrainerName.Text
MTS.Enabled = True
Me.Close()
MTS.AddTrainerFunc()
Else
MessageBox.Show("Please input a name for the trainer in the text box above.")
End If
End Sub
Private Sub btnDel_Click(sender As Object, e As EventArgs) Handles btnDel.Click ''''' Delete Column form
Dim delYN As Integer = MessageBox.Show("Are you sure you want to delete '" & cmbTrainers.Text & "' from the MTS table? The action will be permanent!", "Delete Trainer?", MessageBoxButtons.YesNo)
If delYN = DialogResult.Yes Then
MTS.Enabled = True
MTS.delTrainerFunc()
End If
End Sub
Sorry if this was a bit long winded but... I can't seem to find a way to add columns to the Database quite how I wanted too, neither through googling the answer, nor through simple experimentation, so I came here in the hopes that one of you may be able to help. Thanks in advance for any help you can provide.
EDIT --- I am using oleDB as the connection to sql, if this helps.
EDIT 2 --- Here's a few screenshots in case you wish to have a look at the visual side of the app.
The add form being used. (with the main form in the background. Sorry I couldnt get that on its own - only allowed two links with 6 rep!)
And the delete trainer form. The dropdown lists everyone in the table for you, then prompts you when you click "delete"
EDIT 3 --- Okay, I know the normalizing tables thing that Sean was on about could have worked, but it might have required quite a big change to the server used and to the program as well. I managed to find a simpler way to get this working that calls the sql queries to add or remove columns to the table on the save, only after the changes have been made to the data grid.
Heres some code in case anyone was interested. It's a little messy and can probably be optimized a bit, but this works for me regardless.
` Private Function save()
Try
da.Update(ds)
DataTableColours()
MessageBox.Show("Data updated successfully.")
Catch
MessageBox.Show("Data failed to update properly. Please ensure you are connected to the Baltic network and try again. If the problem persists, seek IT support.")
End Try
'This section reads the SQL server for column names, and adds any that are listed in the DGV, but not the database. I know its a little messy but itll do.
Dim columnnum As Integer = -1
Dim columname As String
For Each column In ds.Tables(0).Columns
columnnum = columnnum + 1
columname = dgvSchedule.Columns(columnnum).HeaderText
If Not ds2.Tables(0).Columns.Contains(columname) Then
MessageBox.Show("Table does not include " & columname)
Dim SqlAddCol As String = "ALTER TABLE MasterTrainerSchedule ADD [" & columname.Trim() & "] nvarchar(255)"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlAddCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End If
Next
columnnum = -1
For Each column In ds2.Tables(0).Columns
columnnum = columnnum + 1
columname = ds2.Tables(0).Columns(columnnum).ColumnName
If Not ds.Tables(0).Columns.Contains(columname) Then
MessageBox.Show("Will Delete " & columname)
Dim SqlDelCol As String = "ALTER TABLE MasterTrainerSchedule DROP COLUMN [" & columname.Trim() & "]"
Using con As New OleDbConnection(cs)
Using cmd As New OleDbCommand(SqlDelCol, con)
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End If
Next
ds2.Tables.Clear()
da2 = New OleDbDataAdapter(sql, cs)
da2.Fill(ds2)
End Function`
I don't know very many details of what you are doing here but here is an example of a more normalized approach to this.
create table Trainers
(
TrainerID int identity
, FirstName varchar(25)
, LastName varchar(25)
, CONSTRAINT PK_Trainers PRIMARY KEY CLUSTERED (TrainerID)
)
create table Courses
(
CourseID int identity
, CourseName varchar(50)
, CONSTRAINT PK_Courses PRIMARY KEY CLUSTERED (CourseID)
)
create table TrainerCourses
(
TrainerID int not null
, CourseID int not null
, StartDate date not null
, EndDate date not null
, DailyStartTime time not null
, CONSTRAINT PK_TrainerCourses PRIMARY KEY CLUSTERED (TrainerID, CourseID, StartDate, DailyStartTime)
, CONSTRAINT FK_TrainerCourses_Trainers FOREIGN KEY (TrainerID) REFERENCES Trainers(TrainerID)
, CONSTRAINT FK_TrainerCourses_Courses FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)
)
I have been banging my head with this script and need to assistance. I am trying to create a registration form that connects to the following sql fields: Acct_ID, Username, Password, FirstName, LastName, Confirmation, RegistrationDate and AccountNum.
What I have been able to do so far is get the form inserted into the database and have a cdosys email sent out to the email address(username) with a querystring attached to a link embedded in the email. The querystring is the AccountNum field from the registration form.
What I want to try to do is update the confirmation field only in the database when the user clicks on the link which looks like this:
http://www.domainname.com/Presenter_Account_Confirm_Registration.asp?AccountNum=2152012319101300766363428210152260.
I verified that the Account Number is transferred to the confirmation page, but I am stumped as to how to update just the confirmation field in the database. Any help would be greatly appreciated. Thank you!
Making some assumptions here, that Acct_ID is an INT, is the same as AccountNum, and that you want to set Confirmation to 1:
<%
Acct_ID = Request.QueryString("AccountNum")
set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = conn ' assume ADODB.Connection has been set up
cmd.CommandType = adCmdText
sql = "UPDATE dbo.tablename SET Confirmation = 1 WHERE Acct_ID = ?"
cmd.Parameters(0).value = Acct_ID
cmd.CommandText = sql
cmd.Execute
%>
I created one of microsoft access 2007 database. which is created two forms. 1.employee form.
table name "tbl employee": ID,IC NO, Name, Office Branch.
2.login form. :
table name "tble User" : UID,Username,Password,Enable,Fullname.
As usual when i login the username(using combobox) and password(using textbox) the login form is working properly as I'm using VB as shown below:-
Private Sub cbo_User_AfterUpdate()
Me.txt_Password = Empty
Me.txt_Password.Enabled = True
Me.txt_Password.SetFocus
End Sub
Private Sub cmd_OK_Click()
'test the stored password is = to the manually entered password
If Me.cbo_User.Column(2) = Me.txt_Password Then
DoCmd.OpenForm "fm_employee", acNormal
DoCmd.Close acForm, "frm_Login"
DoCmd.Close acForm, "fm_switchboard"
Else 'wrong match
MsgBox "Wrong password entered." & _
vbCrLf & "Please re-enter password.", _
vbExclamation, "Invalid Password"
Me.txt_Password.SetFocus 'places the cursor in password control
End If
'If User Enters incorrect password 3 times database will shutdown
intLogonAttempts = intLogonAttempts + 1
If intLogonAttempts > 3 Then
MsgBox "You do not have access to this database.Please contact admin.", _
vbCritical, "Restricted Access!"
Application.Quit
End If
End Sub
Now, I need help How to get the fullname or Username from login form and record into the field when after User Client MODIFIED and SAVE every single record from employee form.
Note: login user is more than 1
If I understand correctly, you want to record who makes changes to a record based on who is logged in to the database. In that case, hide rather than close frmLogin. You can do this with Me.Visible=false. You can then create an event procedure for the BeforeUpdate event of the form fm_employee. In that event procedure, set the field for who modified the record to equal Forms!frmLogin!cbo_User.
I've been working on this script for the last week or so and i'm having major problems trying to understand why it's not working right.
I've got some checkboxes link to email address and all i need is for the corresponding username to go with that email. This script is for users that have registered for different newsletters.
Here is my coding
Set conn = Server.CreateObject("ADODB.Connection")
conn.open connStr
emails = Request("emaillist")
emails = Replace( emails, "'", "''" )
emails = Replace( emails, ", ", "','" )
strSQL = "SELECT name, email FROM emails WHERE email IN ('" & emails & "')"
Set rs = conn.Execute(strSQL)
namesAndEmails = rs.GetRows()
rs.close
for lnRowCounter = 0 To Ubound(namesAndEmails,2)
For lnColumnCounter = 0 To Ubound(namesAndEmails,1)
Response.Write namesAndEmails(lnColumnCounter, lnRowCounter)
Response.write "</P>"
Next
Next
This is part of the whole script, i've changed it around a bit and included the for...next for debugging.
Now for the problem, as shown in the SELECT statement 'name, email', the result completely ignores the email and give me the names only.
I've tried the SQL statement direct and it works perfect showing both name and email together but not in my ASP page. I even tried putting a * in it's place.
strSQL = "SELECT * FROM emails WHERE email IN ('" & emails & "')"
Will return the users id, name, and a few other item's from the DB but not the name and emails together, why?????
It's asp with a SQL Server database
Regards
Rick
Test Results
The values from strSQL when it's set as this:
SELECT name, email
FROM emails
WHERE email IN ('test#test.com','test1#test1.com')
This in SQL will give me the following answer
name | email
jo | test#test.com
fred | test1#test1.com
In asp the answer will be
test#test.com
test1#test1.com
I can't figure out why in SQL it will show the name and email but in ASP it will only show the email and NOT the name.
I've even tried
strSQL = "SELECT * FROM emails WHERE email IN ('test#test.com','test1#test1.com')
and this will produce in ASP all the results EXCEPT name!!!!!
I might not be understanding this completely, but if all you want to do is to output a list of names with their respective email addresses, you could try simplifying to this:
name = rs("name")
email = rs("email")
do while rs.eof <> true
response.write(name & " " & email & "<br />")
rs.movenext
loop
…at least for testing purposes. Alternatively, you could concatenate the name and email in the SQL statement into one column:
SELECT name + '|' + email as nameemail FROM emails WHERE email IN ('" & emails & "')
...will give you "name|email" that you can easily string manipulate.
I'm not 100% sure, but I guess you must swap the rank parameter of the ubound()
for lnRowCounter = 0 To Ubound(namesAndEmails,1)
For lnColumnCounter = 0 To Ubound(namesAndEmails,2)
Try
For i = LBound(namesAndEmails, 2) To UBound(namesAndEmails , 2)
Name = namesAndEmails(0, i)
Email = namesAndEmails(1, i)
Response.Write Name & " " & Email
Next
What if you "View Source" of the output webpage. Sometimes I've had errors that I couldn't see because it came out looking like an invalid tag that the renderer would silently ignore.