sqldatareader error while reading - asp.net

I am extracting the data from mssql server using an sql datareader .. and i want the values within the datareader to be displayed in a datagridview.
how do i check if a particular field is null ??
Row1["EmployeeID"] = x.GetString(2);
when i use this to extract data from sqldatareader (x) it says 'DATA is null.this method or property cannot be used/!!!'
what else can i use then so as to read even null values.

You can use
Row1["EmployeeID"] = (x.GetValue(2) as string);
If you use Getstring it will always throw exception if the value is not a string. If you use GetValue it will return the object and if it's null it will return a DBNull Object.
Edit: Use DataAdapter:
DataSet ds;
using (SqlConnection sqlCon = new SqlConnection(connectionString))
{
sqlCon.Open();
SqlCommand sqlCom = new SqlCommand("Select * From Table",sqlCon);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCom);
sqlDa.Fill(ds);
}
You can then bind the ds to your DataGridView.DataSource.

I would code it more like this:
Row1["EmployeeID"] = x[2] == DbNull ? string.Empty : x.GetString(2);

Related

How can I add a scalar variable for an SQL command In a function that doesn't house my query directly?

I will try to keep this as brief as possible.
I have a function called GetData(ByVal query As String) whose sole purpose is to populate a data table multiple times based on certain conditions. As you can see, the function accepts a string variable where the SQL statement resides. What I am trying to do is add a scalar variable, "#date" in my case, and no matter where I try to add this variable it throws an error stating "Must declare scalar variable #date.
Edit: I should mention that it is throwing the "must declare variable" error on the sda.Fill(dt) line.
GetData Function
Private Shared Function GetData(ByVal query As String) As DataTable
Dim constr As String = ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ConnectionString
Using con As SqlConnection = New SqlConnection(constr)
Using cmd As SqlCommand = New SqlCommand(query)
Dim dt As DataTable = New DataTable()
cmd.Parameters.Add("#date", SqlDbType.Date).Value = Date.Today
Using sda As SqlDataAdapter = New SqlDataAdapter(query, con)
cmd.Parameters.AddWithValue("#date", Date.Today)
sda.Fill(dt)
End Using
Return dt
End Using
End Using
End Function
I am calling the function in a procedure that has the query and handles all of the conditions I need.
Procedure
Dim queryStart As String = "SELECT ( SELECT SUM(DealerNet) FROM Agreement WHERE VoidDate IS NULL "
Dim queryAlias As String = "AS Actual, "
Dim queryStart2 As String = "(SELECT SUM(Amount) FROM AccountingUS.dbo.ProjectedSales "
Dim queryAlias2 As String = "AS Projected "
If chart = "pmtd" Then
Dim queryCondition As String = "AND IssueDate BETWEEN (SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, #date)-1, 0)) AND #date) "
Dim queryCondition2 As String = "WHERE [Month] = MONTH(#date) AND [Year] = YEAR(#date)) "
Dim query As String = queryStart + queryCondition + queryAlias + queryStart2 + queryCondition2 + queryAlias2
Dim xMember1 As String = "Actual"
Dim xMember2 As String = "Projected"
Dim dt As DataTable = GetData(query)
pmtdChart.DataSource = dt
The variable in question is the #date variable in the strings within the "If" statement, the only value it holds is todays date. Currently, I have tried to use "cmd.Parameters.Add("#date", SqlDbType.Date).Value = Date.Today in the GetData function, however, I still receive the same "Must declare scalar variable" error. I have also tried replacing the #date variable with simply "" + Date.Today + "" or a variable that holds todays date, but upon doing so I receive an operand error about "Operand Clash: Date is incompatible with Int"
Any help regarding this issue would be greatly appreciated, I am relatively new to programming and would appreciate any tips or criticisms regarding best practices. If you need any additional information or clarification regarding this issue I would be happy to provide what I can. Thank you in advance.
Ok, a few things:
I would actually pass a command object to that get data routine.
And your issue is you feeding the query to the "adaptor", but NOT supplying the #date parameter to that "sda"
this:
Using sda As SqlDataAdapter = New SqlDataAdapter(query, con)
cmd.Parameters.AddWithValue("#date", Date.Today)
sda.Fill(dt)
End Using
In other words, you NOT EVEN using the cmd object!!!
So, you would need to add the parameter's to the sda object!!
eg this:
Public Function GetData(ByVal query As String) As DataTable
Dim dt As DataTable = New DataTable()
Dim constr As String =
ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ConnectionString
Using con As SqlConnection = New SqlConnection(constr)
Using sda As SqlDataAdapter = New SqlDataAdapter(query, con)
sda.SelectCommand.Parameters.Add("#date", SqlDbType.Date).Value = Date.Today()
sda.Fill(dt)
End Using
End Using
Return dt
End Function
So, yes, you WILL get that error about "#date" not being declared, since you NOT using the cmd object to fill the table, but are using the data adaptor.
So, as a future suggest?
Pick one way, or the other way.
I MUCH over the years have decided that I will use/have/adopt and cookie cut over and over the SqlCommand object.
I find the Sql cmd object better, since:
it has the parameters.
it has a connection object (if you want to use)
it has a data reader built in
So, what this means?
I suggest this code for get data:
Private Shared Function GetData(ByVal query As String) As DataTable
Dim constr As String =
ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ConnectionString
Dim dt As DataTable = New DataTable()
Using con As SqlConnection = New SqlConnection(constr)
Using cmd As SqlCommand = New SqlCommand(query, con))
con.Open()
cmd.Parameters.Add("#date", SqlDbType.Date).Value = Date.Today
dt.Load(cmd.ExecuteReader)
End Using
End Using
Return dt
End Function
So, we don't need a data adaptor. In fact, you only need a adaptor if you going to update the resulting table (think a "adaptive" table to remember this). You not going to update the data, so really, no need to use a "adaptor" at all here. (and sadly, far too many examples use a "adaptor" anyway. They are for ALLOWING update of the data table, and you not doing that!
So, use a command object. Do note that you ALWAYS must then open the confection, but since we have "using" blocks, it will ALWAYS be closed for you.
And note how then we don't create to "use" the "reader" from the adaptor, nor a fill command. (so, we eliminated one whole confusing object!!).
So, in your example, you created a SQL command object, correctly added the parameter to the command object, but THEN DON'T use it, and then decided to create a data adaptor, and use that!!!
So, you could/can leave your code as you had with the sda "prameter " fix I posted above.
However, but I think your better off to use a sql command object.
Note even better?
Pass the command object to the GetData routine.
I have a global "general" purpose routine called MyRstP(), and I pass it a command object, even for just plain jane sql.
but, if you decide to add parameter's, you can!
Do note that parameter's can be added 100% independent of the SQL string, and they can be added before, or after you set the sql string.
And you can add parameter's WITHOUT a valid working connection (or have created one just yet). So, "parameters" are just a colleciton - it does not care about the SQL (well, at least not yet!!).
So, here is my RstP, and I dumped this into a plain jane "module1" which VB has (this means you don't have to create a static class, and this works then just like VB6, or VBA.
So, this:
Public Function MyRstP(cmdSQL As SqlCommand, ByVal Optional strCon As String = "") As DataTable
If strCon = "" Then
strCon = My.Settings.TEST4
End If
Dim rstData As New DataTable
Using conn As New SqlConnection(strCon)
Using (cmdSQL)
cmdSQL.Connection = conn
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
So, now to say fill a grid view, I use this:
Dim strSQL As String =
"SELECT id, HotelName, City FROM tblHotelsA"
Dim cmdSQL As New SqlCommand(strSQL)
GridView1.DataSource = MyRstP(cmdSQL)
GridView1.DataBind()
or say a given date of some such:
How about all hotel visit dates from start of year.
So, this:
Dim strSQL As String =
"SELECT id, HotelName, City FROM tblHotelsA
WHERE VisitDate >= #dtStart"
Dim dtStart As DateTime
dtStart = DateSerial(DateTime.Today.Year, 1, 1)
Dim cmdSQL As New SqlCommand(strSQL)
cmdSQL.Parameters.Add("#dtStart", SqlDbType.DateTime).Value = dtStart
GridView1.DataSource = MyRstP(cmdSQL)
GridView1.DataBind()
note then how I have that MyRstP (like your get data), but I can pass it quite much anything I want, including parameter's from the "calling" code, NOT in that general routine.
Anyway, the above use and adding the parameter's to the "adaptor" will fix this, but I would change over to using just a command object and a connection - the adaptor really not required, and as noted, they really are to be used WHEN you actually want to update the data table, and then send it back to the database in one shot.
If you look closely, you setup a cmd command, but you never actually pass it to the DataTable. So it doesn't know anything about your params.
How about this instead (copied untested from Trying to pass SqlCommand in SqlDataAdapter as parameters):
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ConnectionString))
{
con.Open();
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#date", SqlDbType.Date)
cmd.Parameters.AddWithValue("#date", Date.Today)
using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
{
adp.Fill(dt);
return dt;
}
}
}
Dim dt as new DataTable()
using db as new SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ConnectionString)
db.Open();
using cmd as New SqlCommand(query, con)
cmd.Parameters.Add("#date", SqlDbType.Date).value = Date.Today
//cmd.Parameters.AddWithValue("#date", Date.Today)
using adp as new SqlDataAdapter(cmd)
adp.Fill(dt)
return dt
End using
End using
End using

How to pass SqlCommand parameter dynamically using ASP.NET

I have created a class, in which I am trying to pass query and return the data in a DataTable, but I am unable to pass a parameter to the SqlCommand.
My attempt:
OpenSqlConnection();
SqlCommand sqlCommand = new SqlCommand(inputQuery, sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("", "");
sqlCommand.ExecuteNonQuery();
DataTable dtResult = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(sqlCommand);
da.Fill(dtResult);
CloseSqlConnection();
return dtResult;
In the above code, I am passing SqlCommand as an input query.
How I am calling the above function.
stdFetchDt = new DBManager().GetRecordsByQuery("storedprocedurename");
stdDrop.DataSource = stdFetchDt;
stdDrop.DataBind();
Here DBManager is the class name and GetRecordsByQuery is the method name.
But I'm not able to pass value for sqlCommand.Parameters.AddWithValue("", "");.
My problem: I am unable to pass value in sqlCommand.Parameters.AddWithValue("", "");, because number of value may be multiple.
Please help me with this.
You can send your parameter string with values combined with ',' in C# and then separate theme in the stored procedure :
DECLARE #tags NVARCHAR(400) = 'clothing,road,,touring,bike'
SELECT value
FROM STRING_SPLIT(#tags, ',')
I have Created a class and passing OBJECT & VALUE using List argument.
public DataTable GetRecordsByQuery(string inputQuery, List<string> objectInput, List<string> valInput)
Here in inputQuery String, I am passing name of stored procedure and in objectInput passing object and in valInput passing its value.

Accessing data from sqldatereader within a function

I want to output some data to the user based on their username. This data is held in a table that is linked to the aspnet_Users table. I'm trying to write a sqldatareader as part of a function so I don't have to rewrite the code when it could be called from several pages. I know this is probably very simple buty I can't seem to access the data from outside the function. The function I have so far is as follows:
Public Shared Function AgencyDetails() As SqlDataReader
Dim details As String = "SELECT * FROM tbl_Relationships WHERE ContactSub = #Username"
Dim connString As String = ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString
Using dbConnection As New SqlConnection(connString)
dbConnection.Open()
Dim cmdAgency As New SqlCommand(details, dbConnection)
cmdAgency.Parameters.AddWithValue("#Username", membership.getuser)
Return cmdAgency.ExecuteReader()
End Using
End Function
How can I call this function and access the information on my page? Something like the following?
lblAgencyDetails.text = AgencyDetails(0)
Thanks
The way you have it now, it won't work because you enclosed the connection in a using statement, by the time you return the Reader the connection will be closed and disposed so the reader won't be able to read anything.
What you should do in that function is load the info in a DataTable and return the datatable.
Example:
Public Shared Function AgencyDetails() As DataTable
Dim details As String = "SELECT * FROM tbl_Relationships WHERE ContactSub = #Username"
Dim connString As String = ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString
Using dbConnection As New SqlConnection(connString)
dbConnection.Open()
Dim cmdAgency As New SqlCommand(details, dbConnection)
cmdAgency.Parameters.AddWithValue("#Username", membership.getuser)
Dim dt as new DataTable()
dt.Load(cmdAgency.ExecuteReader())
return dt
End Using
End Function
You can access the rows in the data table by doing:
For Each row as DataRow in dt.Rows
Console.WriteLine(row("ColumnName"))
Next
To be able to retrieve the data from the DataReader object, you should call the Read() method:
While reader.Read()
Console.WriteLine(String.Format("{0}, {1}", _
reader(0), reader(1)))
End While
This method moves the SqlDataReader to the next record.

circular reference in self-nested table 'firstname1'. asp.net

This is the error i am getting "circular reference in self-nested table 'firstname1'".
I want to Hierarchical Data binding. Employee and their supervisor are in the same table.
I am taking reference from http://weblogs.asp.net/alessandro/archive/2008/03/01/part-2-building-and-binding-hierarchical-data-from-the-database-to-the-asp-net-navigation-controls.aspx.
But it is giving error on generating Xml.
using (SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["RMSConnection"].ToString()))
{
string SqlCommand = "SELECT EmployeeId,FirstName,ReportToId FROM tblEmployee";
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(
SqlCommand, con);
adapter.Fill(ds);
ds.Tables[0].TableName = "FirstName1";
DataRelation dr = new DataRelation("pageId_parentId",ds.Tables["FirstName1"].Columns["EmployeeId"], ds.Tables["FirstName1"].Columns["ReportToId"]);
dr.Nested = true;
ds.Relations.Add(dr);
}
//string s= ds.GetXml();
above is my code.
Please Suggest.
You got an infinite loop in your table's data.
You are trying to make a link between EmployeeId and ReportToId but something is wrong.
Your problem is with all your row where the EmployeeId is equal to ReportToId
Exemple:
EmployeeId First Name ReportToId
1 Super 1
In all those cases, you need to set the ReportToId to Null
EmployeeId First Name ReportToId
1 Super Null

database search function

i want to search a record from sql database searching by first name so im using a function in the data layer but it is not working please correct me where i went wrong here is my function:
Public Function searchCustomer(ByVal custFname As String) As DataTable
Dim tabletdata As New DataTable
Dim conn As New SqlConnection(con_string)
conn.Open()
Dim dCmd As New SqlCommand("selectCustomerByFname", conn)
dCmd.CommandType = CommandType.StoredProcedure
Try
dCmd.Parameters.AddWithValue("#Cust_Fnam", custFname)
'dCmd.ExecuteNonQuery()
Dim dadaptr As New SqlDataAdapter(dCmd)
dadaptr.SelectCommand = dCmd
dadaptr.SelectCommand.ExecuteNonQuery()
dadaptr.Fill(tabletdata)
Return tabletdata
Catch
Throw
Finally
dCmd.Dispose()
conn.Close()
conn.Dispose()
End Try
End Function
Fill method opens and close connection implicitly. Fill Method
SUMMARY: The Fill method retrieves
rows from the data source using the
SELECT statement specified by an
associated SelectCommand property. The
connection object associated with the
SELECT statement must be valid, but it
does not need to be open. If the
connection is closed before Fill is
called, it is opened to retrieve data,
then closed. If the connection is open
before Fill is called, it remains
open.
Public Function searchCustomer(ByVal custFname As String) As DataTable
Dim tabletdata As New DataTable
Dim conn As New SqlConnection(con_string)
Dim dCmd As New SqlCommand("selectCustomerByFname", conn)
dCmd.CommandType = CommandType.StoredProcedure
dCmd.Parameters.AddWithValue("#Cust_Fnam", custFname)
Dim dadaptr As New SqlDataAdapter(dCmd)
dadaptr.SelectCommand = dCmd
dadaptr.Fill(tabletdata)
Return tabletdata
End Function

Resources