Need help extracting variables from a While Loop in VB.Net - sql

I'm a novice with my coding so forgive me if my question seems basic but I'm having some trouble extracting my variables from this While Loop in order to then use the results of my SQL query for validation.
This script below is the event handling for a login button on an .aspx form processing an email and login field that will be listed in a correlating MSSQL database:
Public Class _Default
Inherits System.Web.UI.Page
Protected Sub submit_Click(sender As Object, e As EventArgs) Handles submit.Click
Dim Column1 As String
Dim Column2 As String
Dim SQL = "SELECT * FROM Logins WHERE Email='" & email.Text & "' AND Password='" & password.Text & "'"
Dim oSqlDataReader As System.Data.SqlClient.SqlDataReader = Nothing
Using oSqlConnection As New System.Data.SqlClient.SqlConnection("SERVER=[Server Name];UID=[User];PWD=[Pass];DATABASE=[Database Name]")
oSqlConnection.Open()
Using oSqlCommand As New System.Data.SqlClient.SqlCommand(SQL, oSqlConnection)
oSqlDataReader = oSqlCommand.ExecuteReader
While oSqlDataReader.Read
Column1 = oSqlDataReader(name:="Email")
Column2 = oSqlDataReader(name:="Password")
End While
End Using
oSqlConnection.Close()
End Using
If "Column 1 etc."
End if
End Sub
End Class
As far as I can tell my code is working with no errors but every time I try and create an If statement my Variable Column 1 and Column 2 are undeclared making them useless.
If anyone could help with the correct layout for my code or missing areas and an explanation as to where I've gone wrong that'd be great.

If you move the If block inside the loop, do you get closer to the behaviour that you're expecting?
Protected Sub submit_Click(sender As Object, e As EventArgs) Handles submit.Click
Dim Column1 As String
Dim Column2 As String
Dim SQL = "SELECT * FROM Logins WHERE Email='" & email.Text & "' AND Password='" & password.Text & "'"
Dim oSqlDataReader As System.Data.SqlClient.SqlDataReader = Nothing
Using oSqlConnection As New System.Data.SqlClient.SqlConnection("SERVER=[Server Name];UID=[User];PWD=[Pass];DATABASE=[Database Name]")
oSqlConnection.Open()
Using oSqlCommand As New System.Data.SqlClient.SqlCommand(SQL, oSqlConnection)
oSqlDataReader = oSqlCommand.ExecuteReader
While oSqlDataReader.Read
Column1 = oSqlDataReader(name:="Email")
Column2 = oSqlDataReader(name:="Password")
If "Column 1 etc....."
End if
End While
End Using
oSqlConnection.Close()
End Using
End Sub

It could be that your query is returning no rows or that the values returned are dbNull or nothing. I would check the data getting returned and error if appropriate.
Try running the query against the database directly. Are you getting a row back?
To avoid the error, you can declare the string as String.empty
Dim Column1 As String = String.empty
Or, when using it in the if statement check for nothing:
If Column1 Is Not Nothing AndAlso ...

Do not use string concatenation to build your sql query. Instead use sql-parameters to prevent sql injection and other issues.
I must admit that i don't know this syntax: oSqlDataReader(name:="Email"). Use following:
Dim email As String
Dim password As String
Dim sql = "SELECT * FROM Logins WHERE Email=#Email AND Password=#Password"
Using oSqlConnection As New System.Data.SqlClient.SqlConnection("SERVER=[Server Name];UID=[User];PWD=[Pass];DATABASE=[Database Name]")
Using oSqlCommand As New System.Data.SqlClient.SqlCommand(sql, oSqlConnection)
oSqlCommand.Parameters.Add("#Email", SqlDbType.VarChar).Value = email.Text
oSqlCommand.Parameters.Add("#Password", SqlDbType.VarChar).Value = password.Text
oSqlConnection.Open()
Using oSqlDataReader = oSqlCommand.ExecuteReader()
If oSqlDataReader.Read() Then
Dim emailColIndex = oSqlDataReader.GetOrdinal("Email")
Dim pwdColIndex = oSqlDataReader.GetOrdinal("Password")
email = oSqlDataReader.GetString(emailColIndex)
password = oSqlDataReader.GetString(pwdColIndex)
End If
End Using
End Using
End Using ' oSqlConnection.Close() not needed with using '
If email IsNot Nothing AndAlso password IsNot Nothing Then
End If
But instead of initializing two string variables you should implement a Login class that you can initialize and return from the method. You don't want to know the email and the password since you already have them.
Since this is ASP.NET i suggest to look at the available membership provider which are powerful and have a learning curve, but it's definitely worth the time.

Related

Data type mismatch in criteria expression (vb.net, access)

I am trying to take data from the database to the grid. The condition is SELECT * FROM entries WHERE edate='" & Me.dtpDate.Value.Date & "'" But I am getting the error message Data type mismatch in criteria expression. Please see the code below. Also I have attached a screenshot of the error message.
Private Sub dtpDate_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtpDate.Leave
'GetDayBookOpeningBalance()
If Me.lblHeading1.Text <> "Daybook entry" Then
Using MyConnection As OleDb.OleDbConnection = FrmCommonCodes.GetConnection(),
MyAdapter As New OleDb.OleDbDataAdapter("SELECT * FROM entries WHERE edate='" & Me.dtpDate.Value.Date & "'", MyConnection)
'Format(Me.dtpDate.Value.Date, "dd/MM/yyyy"))
If MyConnection.State = ConnectionState.Closed Then MyConnection.Open()
Using MyDataSet As New DataSet
MyAdapter.Fill(MyDataSet, "entries")
Me.grdDayBook.DataSource = MyDataSet.Tables("entries")
Dim DataSetRowCount As Integer = MyDataSet.Tables("entries").Rows.Count
If DataSetRowCount > 0 Then
SetGridProperty()
Else
ShowBlankGrid()
FrmCommonCodes.MessageDataNotFound()
End If
End Using
End Using
Else
ShowBlankGrid()
End If
End Sub
This is exactly what could happen for not using parameterized queries.
I bet that your column edate is a column of type Date/Time but you concatenate your Me.dtpDate.Value.Date to the remainder of your sql string command.
This forces an automatic conversion from DateTime to String but the conversion is not as your database would like to see.
If you use a parameter there is no conversion and the database engine understand exactly what you are passing.
Dim sqlText = "SELECT * FROM entries WHERE edate=#dt"
MyAdapter As New OleDb.OleDbDataAdapter(sqlText, MyConnection)
MyAdapter.SelectCommand.Parameters.Add("#dt", OleDbType.Date).Value = Me.dtpDate.Value.Date
....

VB.net Query wont retrieve data from access database

I have created a query using vb.net with parameters which should allow the query to retrieve data from my access database but however when I click on the button it only shows blank fields but no rows are retrieved from the database. Could you please help me what I am currently doing wrong.
Imports System.Data.OleDb
Public Class RouteToCruise
Private Sub RouteToCruise_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Route_Btn_Click(sender As Object, e As EventArgs) Handles Route_Btn.Click
Try
Dim row As String
Dim connectString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\DeepBlueTables.mdb"
Dim cn As OleDbConnection = New OleDbConnection(connectString)
cn.Open()
Dim CruiseQuery As String = "SELECT Route.RouteName + ', ' + Cruise.CruiseID As CruiseRoute FROM Route INNER JOIN Cruise ON Route.RouteID = Cruise.RouteID WHERE CruiseID = ?"
Dim cmd As New OleDbCommand(CruiseQuery, cn)
'cmd.Parameters.AddWithValue("CruiseID", OleDbType.Numeric).Value = Route_Txt.Text
cmd.Parameters.AddWithValue(("CruiseID"), OleDbType.Numeric)
Dim reader As OleDbDataReader = cmd.ExecuteReader
'RCTable.Width = Unit.Percentage(90.0)
RCTable.ColumnCount = 2
RCTable.Rows.Add()
RCTable.Columns(0).Name = "CruiseID"
RCTable.Columns(1).Name = "RouteName"
While reader.Read
Dim rID As String = reader("RouteID").ToString()
cmd.Parameters.AddWithValue("?", rID)
row = reader("CruiseID") & "," & ("RouteName")
RCTable.Rows.Add(row)
End While
reader.Close()
cn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
If the user enters route name in the text box then the rows should show cruise ID and route name for each of the selected routes. for example if users enters Asia in the text box, clicks on the button then the query should return the cruiseID for the cruises which are going to Asia.
Your use of parameters makes no sense. First you call AddWithValue and provide no value, then you execute the query and then you start adding more parameters as you read the data. Either you call AddWithValue and provide a value, or you call Add and then set the Value on the parameter object created. Either way, it MUST be before you execute the query or it's useless.
myCommand.Parameters.AddWithValue("#ParameterName", parameterValue)
or
Dim myParameter = myCommand.Parameters.Add("#ParameterName", OleDbType.Numeric)
myParameter.Value = parameterValue

How to Trigger Code with ComboBox Change Event

I have a created a database containing historical stock prices. On my form I have two comboboxes, ComboBox_Ticker and ComboBox_Date. When these comboboxes are filled I want to check the database and see if the respective data exists in the database. If it does I want to change the text of a label called Label_If_Present to "In Database".
My problem occurs with the change event. I want all of this to happen once I change the data in the textboxes. I have tried both the .TextChanged and .LostFocus events. The '.TextChanged' triggers the code to early and throws and error in my SQL command statement. The `.LostFocus' event doesn't do trigger my code at all.
Here is my current code:
Public databaseName As String = "G:\Programming\Nordeen Investing 3\NI3 Database.mdb"
Public con As New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & databaseName)
Public tblName As String = "Historical_Stock_Prices"
Private Sub Change_Labels(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox_Ticker.TextChanged, ComboBox_Date.TextChanged
con.Close()
Dim dr As OleDbDataReader
con.Open()
If (File.Exists(databaseName)) Then
Dim restrictions(3) As String
restrictions(2) = tblName
Dim dbTbl As DataTable = con.GetSchema("Tables", restrictions)
If dbTbl.Rows.Count = 0 Then
Else
Dim cmd2 As New OleDb.OleDbCommand("SELECT * FROM " & tblName & " WHERE Ticker = '" & ComboBox_Ticker.Text & "' " & " AND Date1 = '" & ComboBox_Date.Text & "'", con)
dr = cmd2.ExecuteReader
If dr.Read() = 0 Then
'If record does not exist
Label_If_Present.Text = ""
Else
Label_If_Present.Text = "In Database"
End If
con.Close()
End If
Else
End If
End Sub
I have successfully implemented this concept on other forms within my project. This one is slightly different and I can't figure out why I can't get this one to work.
Handling the TextChanged event should work, however you need to set the DropDownStyle to DropDownList so that the Text property can only be a given value.
Then check to see that both comboboxes have values selected. Something like this should work:
If ComboBox_Ticker.Text <> "" AndAlso DateTime.TryParse(ComboBox_Date.Text, Nothing) Then

SQL like with multiple textboxes

For my company I have to create a customer database, which I manage over a VB.NET application.
The application has a few textboxes and a button to "Search" for a customer. If I type in the name of a customer the SQL Select statement is working and populating my datagrid.
But I want to be able to type in the name of the customer AND the street where he lives in. What is the best solution for this? using cases? using a lot of If statements?
Here is my code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If True Then
Dim Conn As New MySqlConnection
Dim da As MySqlDataAdapter
Dim ds As New DataSet
Dim dt As New DataTable
Dim plz As String = plzTextBox.Text
Conn.ConnectionString = "server=localhost;uid=root;pwd=;database=wws; "
Dim sql As String = String.Empty
If vornameTextBox.Text <> String.Empty Then
sql = "vorname = " & vornameTextBox.Text.Trim
End If
If nachnameTextBox.Text <> String.Empty Then
AddCondition(sql, "nachname LIKE '%" & nachnameTextBox.Text.Trim & "%'")
End If
If emailTextBox.Text <> String.Empty Then
AddCondition(sql, "email LIKE '%" & emailTextBox.Text.Trim & "%'")
End If
If plzTextBox.Text <> String.Empty Then
AddCondition(sql, "plz LIKE '%" & plzTextBox.Text.Trim & "%'")
End If
If sql <> String.Empty Then
da = New MySqlDataAdapter("SELECT id,vorname,nachname,email,plz,strasse,nummer,stiege,stock,tuer FROM kunden WHERE " + sql, Conn)
da.Fill(dt)
DataGridView1.DataSource = dt
End If
Else
DataGridView1.ColumnCount = 1
DataGridView1.Rows.Add("1")
End If
End Sub
Thanks in advance!
You can avoid using lots of if statements if you really want, but all you're doing is shunting a load onto your SQL server instead of having it on the client.
The example here is one where you can use lots of if statements or ternary operators to determine how you build your SQL statement, putting a very light processing load on the client, or you can just insert the text value of each of your fields, followed by a percentage sign and surrounded by single quotes, thus making your SQL server evaluate the contents of those fields when it otherwise wouldn't if the field is blank.
It's possible query plan optimization would remove those superfluous field searches, and maybe it wouldn't. I'm typing this on my phone and so don't have anything available to test with.

Inserting variables into a query string - it won't work!

Basically i have a query string that when i hardcode in the catalogue value its fine. when I try adding it via a variable it just doesn't pick it up.
This works:
Dim WaspConnection As New SqlConnection("Data Source=JURA;Initial Catalog=WaspTrackAsset_NROI;User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")
This doesn't:
Public Sub GetWASPAcr()
connection.Open()
Dim dt As New DataTable()
Dim username As String = HttpContext.Current.User.Identity.Name
Dim sqlCmd As New SqlCommand("SELECT WASPDatabase FROM dbo.aspnet_Users WHERE UserName = '" & username & "'", connection)
Dim sqlDa As New SqlDataAdapter(sqlCmd)
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
For i As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(i)("WASPDatabase") Is DBNull.Value Then
WASP = ""
Else
WASP = "WaspTrackAsset_" + dt.Rows(i)("WASPDatabase")
End If
Next
End If
connection.Close()
End Sub
Dim WaspConnection As New SqlConnection("Data Source=JURA;Initial Catalog=" & WASP & ";User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")
When I debug the catalog is empty in the query string but the WASP variable holds the value "WaspTrackAsset_NROI"
Any idea's why?
Cheers,
jonesy
alt text http://www.freeimagehosting.net/uploads/ba8edc26a1.png
I can see a few problems.
You are using concatenation in a SQL statement. This is a bad practice. Use a parameterized query instead.
You are surrounding the password with single quotes. They are not needed and in fact, I'm surprised it even works assuming the password itself does not have single quotes.
You should surround classes that implement IDisposable with a Using block
You should recreate the WASP connection object in GetWASPcr like so:
Public Sub GetWASPAcr()
Dim username As String = HttpContext.Current.User.Identity.Name
Dim listOfDatabaseConnectionString As String = "..."
Using listOfDatabaseConnection As SqlConnection( listOfDatabaseConnectionString )
Using cmd As New SqlCommand("SELECT WASPDatabase FROM dbo.aspnet_Users WHERE UserName = #Username")
cmd.Parameters.AddWithValue( "#Username", username )
Dim dt As New DataTable()
Using da As New SqlDataAdapter( cmd )
da.Fill( dt )
If dt.Rows.Count = 0 Then
WaspConnection = Null
Else
Dim connString As String = String.Format("Data Source=JURA;Initial Catalog={0};User Id={1};Password={2};" _
, dt.Rows(0)("WASPDatabase") _
, ConfigurationManager.AppSettings("WASPDBUserName") _
, ConfigurationManager.AppSettings("WASPDBPassword"))
WaspConnection = New SqlConnection(connString);
End If
End Using
End Using
End Using
End Sub
In this example, listOfDatabaseConnectionString is the initial connection string to the central database where it can find the catalog name that should be used for subsequent connections.
All that said, why would you need a class level variable to hold a connection? You should make all your database calls open a connection, do a sql statement, close the connection. So, five database calls would open and close a connection five times. This sounds expensive except that .NET gives you connection pooling so when you finish with a connection and another is requested to be opened, it will pull it from the pool.
Your string passed into the constructor for this SqlConnection object will be evaluated when the class is instantiated. Your WASP variable (I'm assuming) won't be set until the method you have shown is called.
Might want to quit looking one you have found your database:
For i As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(i)("WASPDatabase") Is DBNull.Value Then
WASP = ""
Else
WASP = "WaspTrackAsset_" + dt.Rows(i)("WASPDatabase")
break
End If
Next
[link text][1]You are building your string on the fly by adding the value of a column to a string. So, for the row in question for the column "WASPDatabase" was tacked on to your string. So you got what it had. On another note, your earlier query of "select ... from ... where ..." where you are manually concatinating the string of a variable makes you WIDE OPEN to SQL-Injection attacks.
Although this link [1]: how to update a table using oledb parameters? "Sample query using parameterization" is to a C# sample of querying with parameterized values, the similar principles apply to most all SQL databases.
At the time you're creating the new connection, WASP is holding the value you want it to be holding? It is a string data type? Try adding .ToString after WASP and see if that helps anything.
Interesting problem. =-)
The problem is, as Paddy already points out, that the WaspConnection object gets initialized before you even have the chance to call GetWASPAcr. Try this:
Public Sub GetWASPAcr()
'[...]
End Sub
Dim _waspConnection As SqlConnection
Public Readonly Property WaspConnection As SqlConnection
Get
If _waspConnection Is Nothing Then
GetWASPAcr()
_waspConnection = New SqlConnection("Data Source=JURA;Initial Catalog=" & WASP & ";User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")
End If
Return _waspConnection
End Get
End Property