Invalid attempt to read when no data is present error - asp.net

I have a function whose sole purpose is to fetch some data when a button is pressed and it's called multiple times. This is the function code:
Function GetData2(ByVal clientNo As Integer) As List(Of SocioInfo)
Dim theResults2 = New List(Of SocioInfo)
Dim connStr = "Data Source=localhost;Initial Catalog=testdb;Integrated Security=True;MultipleActiveResultSets=true"
Using conn = New SqlConnection(connStr)
Dim sql = "SELECT [FirstName], [LastName] FROM [CustInfo] Where ([NumCuenta] = #SocioNum)"
Dim sql2 = "SELECT [AcctName], [AcctNum], [NewAcct], [Balance] From [ACCT_NEW] Where ([AcctNum] = #SocioNum)"
Dim sqlCmd = New SqlCommand(sql, conn)
Dim sqlCmd2 = New SqlCommand(sql2, conn)
sqlCmd.Parameters.AddWithValue("#SocioNum", CDbl(txtInput.Text))
sqlCmd2.Parameters.AddWithValue("#SocioNum", CDbl(txtInput.Text))
conn.Open()
Dim rdr = sqlCmd.ExecuteReader
Dim rdr2 = sqlCmd2.ExecuteReader
While rdr.Read
theResults2.Add(New SocioInfo With {
.Nombre = rdr.GetString(0),
.LastName = rdr.GetString(1)
})
End While
While rdr2.Read
theResults2.Add(New SocioInfo With {
.CuentaName = rdr.GetString(0),
.AcctNum = rdr.GetValue(1),
.AcctFull = rdr2.GetValue(2),
.Balance = rdr2.GetValue(3)
})
End While
End Using
Return theResults2
End Function
I am not 100% sure if this is the best way to do this (basically need to get data from two different tables). Thing is, while Rdr shows me no error, Rdr2 just blows in the face. The exception is this:
Invalid attempt to read when no data is present.

In the second loop you are trying to use the first SqlDataReader but this is not possible because the first loop has already reached the end of the input data.
If you need joined data between the two tables a better approach is to use just one query using the JOIN operator. This query works assuming that each customer in the CustInfo table has one account in the ACCT_NEW table
Dim sql = "SELECT c.FirstName, c.LastName, a.AcctName, a.AcctNum, a.NewAcct, a.Balance " & _
"FROM CustInfo c INNER JOIN ACCT_NEW a ON a.AcctNum = c.NumCuenta " & _
"WHERE NumCuenta = #SocioNum "
Using conn = New SqlConnection(connStr)
Dim sqlCmd = New SqlCommand(sql, conn)
sqlCmd.Parameters.AddWithValue("#SocioNum", CDbl(txtInput.Text))
conn.Open()
Dim rdr = sqlCmd.ExecuteReader
While rdr.Read
theResults2.Add(New SocioInfo
With {
.Nombre = rdr.GetString(0),
.LastName = rdr.GetString(1)
.CuentaName = rdr.GetString(2),
.AcctNum = rdr.GetValue(3),
.AcctFull = rdr.GetValue(4),
.Balance = rdr.GetValue(5)
})
End While
End Using

Related

Create report dynamically using ParameterFields

I have to create crystal report dynamically by using ParameterFields. - In that a single parameter have to call particular row from MySQL database dynamically. Now I called multiple values from MySql database static and single.
I need to call particular row(dynamically) from MySQL database.
Dim sql_Sel As String
Dim hIssId As Integer = 0
Dim connectionInfo1 As New ConnectionInfo()
Dim SqlCon As String = "Data source= *****"
hIssId = Request.QueryString("patID")
Try
CrystLabl.ReportSource = Nothing
Me.SqlCon.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("xyz").ConnectionString
Me.SqlCon.Open()
Dim crystalReport As New ReportDocument()
sql_Sel = "exec DI_Details #opt=1"
Dim DA As SqlDataAdapter = New SqlDataAdapter(sql_Sel, SqlCon)
Dim DG As New DataSet
DG.DataSetName = "DataSet.xsd"
DA.Fill(DG, "DataTable1")
Dim paramFields3 As New CrystalDecisions.Shared.ParameterFields()
For Each i As String In sql_Sel
Dim paramField31 As New CrystalDecisions.Shared.ParameterField()
Dim discreteVal1 As New CrystalDecisions.Shared.ParameterDiscreteValue()
discreteVal1 = New ParameterDiscreteValue()
paramField31.ParameterFieldName = "My Parameter"
discreteVal1.Value = ((DG.Tables(0).Rows(0).Item(1)) & (DG.Tables(0).Rows(0).Item(2)) & (DG.Tables(0).Rows(0).Item(3)) >(DG.Tables(0).Rows(0).Item(6)))
paramField31.CurrentValues.Add(discreteVal1)
paramFields3.Add(paramField31)
Next
CrystLabl.ParameterFieldInfo = paramFields3
CrystLabl.ReportSource = "CrystalReport.rpt"
CrystLabl.RefreshReport()
Catch ex As Exception
Finally
End Try
End Sub

vb.net OleDbDataAdapter not working with Select From Where

If I Debug this I just get a Invalid Columnname Error("Name of the Object"). I am using a SQL database.
Protected Sub ddlKunden_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlKunden.SelectedIndexChanged
Dim strSql As String
Dim kontakt As String = ddlKunden.SelectedItem.Value
Dim dtbP As DataTable
Using connection As OleDbConnection = New OleDbConnection(strConnection)
connection.ConnectionString = strConnection
connection.Open()
'Kontaktpersonen laden
strSql = "SELECT * FROM Kontaktpersonen WHERE Nr =" & Chr(34) & kontakt & Chr(34)
dtbP = New DataTable()
Using dad As New OleDbDataAdapter(strSql, connection)
dad.Fill(dtbP)
End Using
ddlKontaktperson.Items.Clear()
ddlKontaktperson.DataSource = dtbP
ddlKontaktperson.DataTextField = "AP_Nam"
ddlKontaktperson.DataValueField = "ID"
ddlKontaktperson.DataBind()
End Using
ddlKontaktperson.Visible = True
End Sub
The Error pops at
dad.fill(dtbP)
It should select all rows Where Nr="SELECTED VALUE" and you select it in a dropdownlist. And all these rows should be saved in a Datatable then and are used in another dropdownlist.
It works when I try the exact same thing without the where.
Example:
'Kunden laden
strSql = "SELECT * FROM Kontakte"
dtbK = New DataTable()
Using dad As New OleDbDataAdapter(strSql, connection)
dad.Fill(dtbK)
End Using
ddlKunden.Items.Clear()
ddlKunden.DataSource = dtbK
ddlKunden.DataTextField = "Nr"
ddlKunden.DataValueField = "Nr"
ddlKunden.DataBind()
Please try following code
You do not need to use "'" around parameters
Just add these values as a parameter to the oledbcommand with its value and type
Otherwise, your sql command will be vulnerable to sql injection
Dim strConnection As String = "Provider=sqloledb;Data Source=(local);" &
"Initial Catalog=kodyaz;" &
"User Id=sa;Password=sa"
Dim kontakt As Int32 = 1
Dim dtbP As DataTable
Using connection As OleDbConnection = New OleDbConnection(strConnection)
connection.Open()
Dim cmd As New OleDbCommand()
cmd.Connection = connection
cmd.CommandText = "SELECT * FROM Kontaktpersonen WHERE Nr = ?"
cmd.Parameters.AddWithValue("Nr", kontakt)
dtbP = New DataTable()
Using dad As New OleDbDataAdapter(cmd)
dad.Fill(dtbP)
End Using
End Using

What's wrong with my Count Query asp.net

Public state_name as String
state_name = Textbox1.Text
Dim constr As String = ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString
Dim query As String = "SELECT Count(cities) FROM state_table WHERE state_name=" & state_name
Using conn As New SqlConnection(constr)
Using comm As New SqlCommand()
conn.Open()
With comm
.Connection = conn
.CommandText = query
.CommandType = CommandType.Text
End With
Dim count As Int16 = Convert.ToInt16(comm.ExecuteScalar())
Label1.Text = count
End Using
End Using
The code shows an error
Invalid column name 'California'.
But California is already present in my State table, I want to count all the cities comes under state_name= california which I have entered in my State table.
I want the output as
California (3)
You want to use Parameterized Query to avoid SQL Injection.
Dim constr As String = ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString
Dim query As String = "SELECT Count(cities) FROM state_table WHERE state_name=#State_Name"
Using conn As New SqlConnection(constr)
Using comm As New SqlCommand()
conn.Open()
With comm
.Connection = conn
.CommandText = query
.CommandType = CommandType.Text
.Parameters.AddWithValue("#State_Name", state_name)
End With
Dim count As Int16 = Convert.ToInt16(comm.ExecuteScalar())
Label1.Text = count
End Using
End Using
Because you didn't surround your variable with quotes. "state_name = '" + state_name + "'"
But, you should use a parameter instead.

Trouble getting date value

I am modifying a webpage. Webpage is using visual basic and my database is a SQL database.
The webpage gives me the total Sick, Comp, and Vacation time off. Right now, I get the logon name of whoever's logged onto the computer, and I look up the EmployeeID in a tblEmployees so I can search tblTimeAvailable by the EmployeeID, and then add up the different times.
I want to also get the StartDate from tblEmployees so I can also search by anniversary date (after I calculate it from the Start Date). I'm getting an error "Value of type 'Integer' cannot be converted to 'Date' on the rvsd=command2.ExecuteNonQuery line. Here's my code:
Dim rve As Object
Dim rvsd As Date
Dim dt As Date = Today
'Get network login name (name only)
split = windowsLoginName.Split("\".ToCharArray)
vname = split(1)
'Get employeeid from table that matches login name
Dim Connection As String = "Data Source=WillSQL\ict2;Initial Catalog=timesql_testing;Integrated Security=SSPI"
Using con As New SqlConnection(Connection)
Dim sqlemp As String = "SELECT EmployeeID FROM tblEmployees where login = #loginname"
Dim sqlstdt As String = "SELECT StartDate FROM tblEmployees where login = #loginname"
Dim command As New SqlCommand(sqlemp, con)
Dim command2 As New SqlCommand(sqlstdt, con)
con.Open()
command.Parameters.Add(New SqlParameter With {.ParameterName = "#loginname", .SqlDbType = SqlDbType.NVarChar, .Value = vname})
command2.Parameters.Add(New SqlParameter With {.ParameterName = "#loginname", .SqlDbType = SqlDbType.NVarChar, .Value = vname})
rve = command.ExecuteScalar
rvsd = command2.ExecuteNonQuery
End Using
Dim theDateThisYear As Date
theDateThisYear = DateSerial(Year(Now), Month(rvsd), Day(rvsd))
If theDateThisYear < Now() Then
theDateThisYear = DateAdd("yyyy", 1, theDateThisYear)
End If
Dim NextAnniversary As Date = theDateThisYear
MsgBox(NextAnniversary)
'Get Sick Time - DOES NOT INCLUDE CHECKING TO MAKE SURE LESS THAN ANNIV DATE YET
Using con As New SqlConnection(Connection)
Dim sqls1 As String = "Select SUM(NoofHours) as Total from tblTimeAvailable where workcode = 1 and EmployeeID = #emp"
Dim command As New SqlCommand(sqls1, con)
con.Open()
command.Parameters.Add(New SqlParameter With {.ParameterName = "#emp", .SqlDbType = SqlDbType.NVarChar, .Value = rve})
rvsa = command.ExecuteScalar
End Using
Thanks in advance for any help you can give me!
Assuming that the column [StartDate] in the database has a type of DateTime then all you need to do is
rvsd = CDate(command2.ExecuteScalar)
Although you could have retrieved both values with one query:
SELECT [EmployeeID], [StartDate] FROM [tblEmployees] where [login] = #loginname"
and so
Dim rve As String
Dim rvsd As Date
Dim connStr As String = "Data Source=WillSQL\ict2;Initial Catalog=timesql_testing;Integrated Security=SSPI"
Dim sql = "SELECT [EmployeeID], [StartDate] FROM [tblEmployees] where [login] = #loginname"
Using conn As New SqlConnection(connStr)
Using cmd As New SqlCommand(Sql, conn)
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#loginname", .SqlDbType = SqlDbType.NVarChar, .Value = vname})
conn.Open()
Dim rdr = cmd.ExecuteReader()
If rdr.HasRows Then
rdr.Read()
rve = rdr.GetString(0)
rvsd = rdr.GetDateTime(1)
End If
End Using
End Using

retrieving whole database into dataset

I have access db with 3 different tables,I want to load the whole database into dataset so I will be able to work with the data without load the db serval times.
all the examples of working with dataset are showing how to get part of the database using ".fill"
for example :
OleDbCommand CommandObject = new OleDbCommand ("Select * from employee");
OleDbAdapter myDataAdapter = new OleDbAdapter (null, con);
myDataAdapter.SelectCommand = CommandObject;
myDataAdapter.Fill (myDataSet, "EmployeeData");
this example load only from employee but how can I etrieve the all tables in once into dataset?
in xml for instance there is command to load all the document to dataset with:" dataset.ReadXml"
How can I achive it in access db?
Thanks for any help
Baaroz
Protected Function getDataSetAndFill(ByRef connection As OleDb.OleDbConnection,
Optional ByVal isExportSchema As Boolean = True) As DataSet
Dim myDataSet As New DataSet
Dim myCommand As New OleDb.OleDbCommand
Dim myAdapter As New OleDb.OleDbDataAdapter
myCommand.Connection = connection
'Get Database Tables
Dim tables As DataTable = connection.GetOleDbSchemaTable( _
System.Data.OleDb.OleDbSchemaGuid.Tables, _
New Object() {Nothing, Nothing, Nothing, "TABLE"})
'iterate through all tables
Dim table As DataRow
For Each table In tables.Rows
'get current table's name
Dim tableName As String = table("TABLE_NAME")
Dim strSQL = "SELECT * FROM " & "[" & tableName & "]"
Dim adapter1 As New OleDb.OleDbDataAdapter(New OleDb.OleDbCommand(strSQL, connection))
adapter1.FillSchema(myDataSet, SchemaType.Source, tableName)
'Fill the table in the dataset
myCommand.CommandText = strSQL
myAdapter.SelectCommand = myCommand
myAdapter.Fill(myDataSet, tableName)
Next
''''''''''''''''''''''''''''''''''''''
'''' Add relationships to dataset ''''
''''''''''''''''''''''''''''''''''''''
'First, get relationships names from database (as well as parent table and child table names)
Dim namesQuery As String = "SELECT DISTINCT szRelationship, szReferencedObject, szObject " & _
"FROM MSysRelationships"
Dim namesCommand As New System.Data.OleDb.OleDbCommand(namesQuery, connection)
Dim namesAdapter As New System.Data.OleDb.OleDbDataAdapter(namesCommand)
Dim namesDataTable As New DataTable
namesAdapter.Fill(namesDataTable)
'Now, get MSysRelationship from database
Dim relationsQuery As String = "SELECT * FROM MSysRelationships"
Dim command As New System.Data.OleDb.OleDbCommand(relationsQuery, connection)
Dim adapter As New System.Data.OleDb.OleDbDataAdapter(command)
Dim relationsDataTable As New DataTable
adapter.Fill(relationsDataTable)
Dim relationsView As DataView = relationsDataTable.DefaultView
Dim relationName As String
Dim parentTableName As String
Dim childTablename As String
Dim row As DataRow
For Each relation As DataRow In namesDataTable.Rows
relationName = relation("szRelationship")
parentTableName = relation("szReferencedObject")
childTablename = relation("szObject")
'Keep only the record of the current relationship
relationsView.RowFilter = "szRelationship = '" & relationName & "'"
'Declare two arrays for parent and child columns arguments
Dim parentColumns(relationsView.Count - 1) As DataColumn
Dim childColumns(relationsView.Count - 1) As DataColumn
For i As Integer = 0 To relationsView.Count - 1
parentColumns(i) = myDataSet.Tables(parentTableName). _
Columns(relationsView.Item(i)("szReferencedColumn"))
childColumns(i) = myDataSet.Tables(childTablename). _
Columns(relationsView.Item(i)("szColumn"))
Next
Dim newRelation As New DataRelation(relationName, parentColumns, childColumns, False)
myDataSet.Relations.Add(newRelation)
Next
If isExportSchema Then
Dim schemaName = GetXmlSchemaFileName()
If File.Exists(schemaName) Then File.SetAttributes(schemaName, FileAttributes.Normal)
myDataSet.WriteXmlSchema(schemaName)
End If
Return myDataSet
End Function
You should just call the OleDbDataAdapter.Fill method with different SelectCommands and pass the same DataSet but different table names inside. In this case, your dataSet will contain different filled tables.

Resources