Idatareaders not returning values from database - asp.net

In my codebehind I have this vb:
Dim reader as idatareader = includes.SelectDepartmentID(PageID)
While reader.Read
Did = reader("departmentid")
GroupingHeading = reader("heading")
Folder = reader("folder")
If reader("OwnBanner") Is DBNull.Value Then
OwnBanner = String.Empty
Else
OwnBanner = reader("ownbanner")
End If
Then in my class I have:
Public Function SelectDepartmentID(ByVal PageID As Integer) As IDataReader
Dim Command As SqlCommand = db.GetSqlStringCommand("sql")
db.AddInParameter(Command, "#pageid", Data.DbType.Int32, PageID)
Dim reader As IDataReader = db.ExecuteReader(Command)
reader.Read()
Return reader
End Function
No Errors are being presented yet nothing is being returned by the reader. Is there an error in my code?
Thanks.

Try removing the
reader.Read()
line from SelectDepartmentID.

You are skipping the first row of the reader. Remove the reader.Read() statement in the SelectDepartmentID function just prior to the return statement.
Any function that returns a reader should make no assumptions about what the calling code will do with it and just return it unmodified.

Related

Get Oracle.DataAccess.Types.OracleClob instead of actual value

I'm having an issue, I'm calling a procedure on oracle 11g, the prucedure receives a clob and responds with a different CLOB, a VARCHAR2 and a Number. The procedure is called from a ASP.NET (on Visual Basic) webpage using oracle data provider (ODP.NET), I can call the procedure successfully, view the VARCHAR2 and NUMBER returned values, but when I try to see the returned value of the returning CLOB all I get is "Oracle.DataAccess.Types.OracleClob" instead of a expecting XML
I know the returned XML is generated because on the store procedure I create a txt file where it shows the expected result
My code it's pretty simple right now:
Function Index() As String 'ActionResult
Dim xml_message As String
Dim oradb As String = "Data Source=127.0.0.1;User Id=id;Password=pass;"
Dim conn As New OracleConnection(oradb)
Dim oracleDataAdapter As New OracleDataAdapter
oracleDataAdapter = New OracleDataAdapter()
Dim cmd As New OracleCommand
cmd.Connection = conn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "Common.GetDriverPoints"
cmd.BindByName = True
Dim driver_input As New OracleParameter()
driver_input = cmd.Parameters.Add("p_driver", OracleDbType.Clob)
driver_input.Direction = ParameterDirection.Input
driver_input.Value = <THE_SENDED_XML_VALUE>
Dim driver_output As New OracleParameter()
driver_output = cmd.Parameters.Add("p_output", OracleDbType.Clob)
driver_output.Direction = ParameterDirection.Output
Dim error_flag As New OracleParameter()
error_flag = cmd.Parameters.Add("p_Return", OracleDbType.Int16)
error_flag.Direction = ParameterDirection.Output
Dim error_desc As New OracleParameter()
error_desc = cmd.Parameters.Add("p_ReturnDesc", OracleDbType.Varchar2, 100)
error_desc.Direction = ParameterDirection.Output
conn.Open()
cmd.ExecuteNonQuery()
Dim output As String
output = driver_output.Value.ToString() 'This only returns Oracle.DataAccess.Types.OracleClob
conn.Close()
conn.Dispose()
Return output
End Function
Also, the generated xml is around 55Kb, sometimes it's bigger
Thank you
I manage to find the answer, In case someone have the same problem, basically what has to be done is create another clob, used only on for vb.net, that clob will receive the value of the parameter output from the procedure, then cast to a string variable the local clob.
Example:
Dim output As String
Dim myOracleClob As OracleClob = driver_output.Value
output = System.Convert.ToString(myOracleClob.Value)
Now the "output" variable holds the actual message of the clob.
Hope this helps anybody with the same problem.

Dropdownlist loaded from function or method

I have a dropdownlist which I constantly use.
I wrote a method to load this dropdown.
Though when I call the method only the Text part of the item is passed.
This is the method
Public Shared Function ddlLoadResumes() As DropDownList
Dim connString As String = ConfigurationManager.ConnectionStrings("LocalSqlServer").ConnectionString
Dim conn As SqlConnection = New SqlConnection(connString)
Dim ddSelectResumeList As New DropDownList
Dim dtResumes As New DataTable()
Dim comm As SqlCommand = New SqlCommand("usr_SelectResumeList", conn)
comm.CommandType = CommandType.StoredProcedure
comm.Parameters.Add("#UserName", SqlDbType.VarChar, 50).Value = Membership.GetUser().UserName
Try
Dim daResumes As New SqlDataAdapter(comm)
conn.Open()
daResumes.Fill(dtResumes)
ddSelectResumeList.DataSource = dtResumes
ddSelectResumeList.DataTextField = "ResumeName"
ddSelectResumeList.DataValueField = "Res_ID"
ddSelectResumeList.DataBind()
' Handle the error
Catch ex As Exception
Finally
conn.Close()
End Try
Return ddSelectResumeList
End Function
and this is how I call it
ddSelectResume.DataSource = MailClass.ddlLoadResumes.Items
ddSelectResume.DataBind()
Dim ltitem As ListItem
For Each ltitem In ddSelectResume.Items
Response.Write(ltitem.Value + "-----" + ltitem.Text)
Next returns only the text part
I need both DataTextField and DataValueField.
Thank you in advance
This seems like kind of an odd approach. One thing to resolve your issue would be to just set the ddSelectResume equal to the DropDownList object your Function is returning:
ddSelectResume = MailClass.ddlLoadResumes
Dim ltitem As ListItem
For Each ltitem In ddSelectResume.Items
Response.Write(ltitem.Value + "-----" + ltitem.Text)
Next
Though I think a better approach would be to just have "ddlLoadResumes return the DataTable (dtResumes), and set that as the datasoure of ddSelectResumes (you'd still have to set the DataTextField and DataValueField properties).

Using a stringbuilder as a parameter to a stored procedure and returning a dataset

I have a couple of problems relating to one of the parameters passing a number of values to a stored procedure and the result that comes back converting to dataset in order for this to be bound to an MS ReportViewer.
The error I am getting says that the the reader is closed.
My relevant code snippet is:
Dim _listOfSites As New StringBuilder()
Dim _resultDataSet As DataSet = New DataSet
Using _conn as New SqlConnection()
_conn.ConnectionString = _connString
Try
For i as Integer = 0 To _sites.Count - 1
_listOfSites.Append(_sites(i))
If _sites.Count > 1 Then
_listOfSites.Append(",")
End If
Next
_conn.Open()
Dim _sqlCommand as SqlCommand = New SqlCommand("GetResults", _conn)
_sqlCommand.Parameters.Add("#Sites", SqlDbType.Varchar).Value = _listOfSites
_sqlCommand.Parameters.Add("#Date", SqlDbType.Date).Value = _date
Dim _reader as SqlDataReader = _sqlCommand.ExecuteReader
While _reader.Read
_resultDataSet.Load(_reader, LoadOption.PreserveChanges, New String() {"RegionalResults"})
End While
_reader.Close()
Can anyone please help?
Thanks
Looks like you should not call _reader.Read as _resultDataSet.Load do it by itself and it could close the SqlDataReader. So instead of
Dim _reader as SqlDataReader = _sqlCommand.ExecuteReader
While _reader.Read
_resultDataSet.Load(_reader, LoadOption.PreserveChanges, New String() {"RegionalResults"})
End While
_reader.Close()
Just write
Using _reader as SqlDataReader = _sqlCommand.ExecuteReader
_resultDataSet.Load(_reader, LoadOption.PreserveChanges, New String() {"RegionalResults"})
End Using
Hope that helps

Return more than one value in list vb.net

Before telling you the problem, excuse me for my bad english, I only know the basic
I have a function with a query and I want to return it, I was doing this:
Public Function obtenerDataAjuste(ByVal id As Integer)
Dim ajuste As New Ajuste
Dim cmd as New SqlCommand("usp_obtenerDataAjuste",cn.getCN")
cmd.CommandType = CommandType.StoredProcedure
cn.getCN().Open()
Dim dr as SqlDataReader
dr = cmd.ExecuteReader
Dim ajustelist As New List(Of Ajuste)
While dr.Read
ajuste.pesomix = dr("PesoMix")
ajuste.pesoprod = dr("PesoProd")
ajuste.unidad = dr("UNIDAD_EMPAQUE")
End While
cn.getCN().Close()
Return ajustelist.ToArray
End Function
but I think is wrong because I was calling this function into my code behind:
Dim opd As New OPDAO
For Each objAjuste In opd.obtenerDataAjuste(CInt(Session("idop")))
Dim pesomix As Decimal = objAjuste.pesomix
Dim pesoprod As Decimal = objAjuste.pesoprod
Dim empaque As Integer = objAjuste.unidad
'Reajuste unidad ajustado
Dim unidadajustado As Double = pesomix / pesoprod
Session("undajustado") = Convert.ToInt32(unidadajustado)
'Reajuste paquete ajustado
Dim paqueteajustado As Double = Session("undajustado") / empaque
Session("pqtajustado") = paqueteajustado
Next
and it doesn't work for me, it returns the last record. Can anyone help me please?.
Thanks!
you are not adding anything to your list. You also need to initialize a new Ajuste object inside the While dr.Read loop.
That's the reason why you only see the last value right now, because you constantly overwrite your Ajuste object that you initialised outside the while loop.
Dim ajustelist As New List(Of Ajuste)
While dr.Read
Dim ajuste As New Ajuste // <-- add this
ajuste.pesomix = dr("PesoMix")
ajuste.pesoprod = dr("PesoProd")
ajuste.unidad = dr("UNIDAD_EMPAQUE")
ajustelist.Add(ajuste) // <-- and this
End While
Each time through the For Each loop, you will overwrite what you previously put into Session("undajustado") which will end up being the last item in the loop when its done.
I need to know what you are trying to accomplish before being able to help you.

SQL Server CE does not support DataReader.HasRows?

I have the following code;
Dim rdr As SqlCeDataReader = cm_sel.ExecuteReader
If rdr.HasRows Then
While rdr.Read
Documents.DeleteDocument(rdr.Item("fID"))
End While
End If
The error I get is:
SQL Server Compact does not support calls to HasRows property if the
underlying cursor is not scrollable.
So how am I supposed to check if data exists before actually reading the DataReader?
EDIT
the whole code:
Dim con As New SqlCeConnection(ConfigurationManager.ConnectionStrings("MyConnectionString").ToString)
Dim cm_sel As New SqlCeCommand("SELECT fID FROM Files WHERE fCatID=" & catID, con)
Try
con.Open()
Dim rdr As SqlCeDataReader = cm_sel.ExecuteReader
If rdr.HasRows() Then
While rdr.Read
Documents.DeleteDocument(rdr.Item("fID"))
End While
End If
Return "{'result':'ok'}"
Catch ex As Exception
Return "{'result':'error'}"
Finally
con.Close()
con.Dispose()
End Try
You could call directly reader.Read since will return false if there are no rows. Simply remove the if statement surrounding the while.
UPDATED CODE:
Dim rdr As SqlCeDataReader = cm_sel.ExecuteReader
While rdr.Read
Documents.DeleteDocument(rdr.Item("fID"))
End While
This works fine for the above problem.
Dim hasrows As Boolean
hasrows = False
While (rdr.Read())
hasrows = True
End While
If (hasrows) Then
--do something
else
--do something else
end if
If you assign hasrows function to any Boolean and try to use it, the reader can jump to second record. The above solution will avoid that scenario as well.

Resources