Asp.Net select in Sql - asp.net

This is going to be very simple I know. I have seen so many different ways of using sql in asp.net with no real standard. What I want to know is how to cleanly select from an sql database in asp.net and retrieve multiple records. For example: select all userids.
String sql =
"SELECT [UserId] FROM [UserProfiles] WHERE NOT [UserId] = 'CurrentUserId'";
string strCon = System.Web
.Configuration
.WebConfigurationManager
.ConnectionStrings["SocialSiteConnectionString"]
.ConnectionString;
SqlConnection conn = new SqlConnection(strCon);
SqlCommand comm = new SqlCommand(sql, conn);
conn.Open();
/*
This is where I need to know how to retrieve the information from the
above command(comm). I am looking for something similiar to php's
mysql_result. I want to access the records kind of like an array or some
other form of retrieving all the data.
Also when the new SqlCommand is called...does that actual run the
SELECT STATEMENT or is there another step.
*/
conn.Close();

I think that this is what you are looking for.
String sql = "SELECT [UserId] FROM [UserProfiles] WHERE NOT [UserId] = 'CurrentUserId'";
string strCon = System.Web
.Configuration
.WebConfigurationManager
.ConnectionStrings["SocialSiteConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(strCon);
SqlCommand comm = new SqlCommand(sql, conn);
conn.Open();
SqlDataReader nwReader = comm.ExecuteReader();
while (nwReader.Read())
{
int UserID = (int)nwReader["UserID"];
// Do something with UserID here...
}
nwReader.Close();
conn.Close();
I do have to say, though, that the overall approach can use a lot of tuning. First, you could at least start by simplifying access to your ConnectionString. For example, you could add the following to your Global.asax.cs file:
using System;
using System.Configuration;
public partial class Global : HttpApplication
{
public static string ConnectionString;
void Application_Start(object sender, EventArgs e)
{
ConnectionString = ConfigurationManager.ConnectionStrings["SocialSiteConnectionString"].ConnectionString;
}
...
}
Now, throughout your code, just access it using:
SqlConnection conn = new SqlConnection(Global.ConnectionString);
Better yet, create a class in which the "plumbing" is hidden. To run the same query in my code, I'd just enter:
using (BSDIQuery qry = new BSDIQuery())
{
SqlDataReader nwReader = qry.Command("SELECT...").ReturnReader();
// If I needed to add a parameter I'd add it above as well: .ParamVal("CurrentUser")
while (nwReader.Read())
{
int UserID = (int)nwReader["UserID"];
// Do something with UserID here...
}
nwReader.Close();
}
This is just an example using my DAL. However, notice that there is no connection string, no command or connection objects being created or managed, just a "BSDIQuery" (which does lots of different things in addition to that shown). Your approach would differ depending on the tasks that you do most often.

Most of the time, I use this (note that I am also using a connection pooling approach):
public DataTable ExecuteQueryTable(string query)
{
return ExecuteQueryTable(query, null);
}
public DataTable ExecuteQueryTable(string query, Dictionary<string, object> parameters)
{
using (SqlConnection conn = new SqlConnection(this.connectionString))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = query;
if (parameters != null)
{
foreach (string parameter in parameters.Keys)
{
cmd.Parameters.AddWithValue(parameter, parameters[parameter]);
}
}
DataTable tbl = new DataTable();
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(tbl);
}
return tbl;
}
}
}

Here's an adaption of your existing code:
String sql = "SELECT [UserId] FROM [UserProfiles] WHERE [UserId] != #CurrentUserId";
string strCon = System.Web
.Configuration
.WebConfigurationManager
.ConnectionStrings["SocialSiteConnectionString"].ConnectionString;
DataTable result = new DataTable();
using (var conn = new SqlConnection(strCon))
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add("#CurrentUserID", SqlDbType.Int).Value = CurrentUserID;
conn.Open();
result.Load(cmd.ExecuteReader());
}

Creating a SqlCommand doesn't execute it at all.
The command will be executed when you call ExecuteReader or something similar.
If you want something which will fetch all the results into memory, you should be looking at DataSet/DataTable. There's a tutorial for them here - or there are plenty of others on the net, and any decent ADO.NET book will cover them too.
If you don't want to fetch them all into memory at once, then ExecuteReader it the method for you. That will return a SqlDataReader which is like a database cursor - it reads a row at a time, and you ask for individual columns as you want them, calling Read to get to the next row each time.

Whereas in PHP you'd do something like,
while ($row = mysql_fetch_array ($result))
{
//this assumes you're doing something with foo in loop
$foo = $row["userid"];
//using $foo somehow
}
in .NET, you do something different. Believe me, originating from a PHP background, the transition from PHP to .NET is not easy. There's a lot of things that will seem bizarre. After a while though, it will make sense! Just stick it out. I personally like it better.
Ok.. assuming you have a DataSet like you say, you can do something like this,
//assuming you have a DataSet called myDataSet
for (int i = 0; i < myDataSet.Tables[0].Rows.Count; i++)
{
//likewise assuming here you're doing something with foo in loop
string foo = myDataSet.Tables[0].Rows[i]["userid"].ToString();
//similarly do something with foo in loop
}
That does the same thing as the PHP snippet.

Related

Nested Queries In ASP.Net Without Async

I have the following code and basically I want it go step by step using the If statements. When I run this however I get this asp error: "This command requires an asynchronous connection. Set "Asynchronous Processing=true" in the connection string."
On this bit of code:
"addToTable.BeginExecuteReader();"
However I do not want it to by async I want it to run the subsequent queries only if the previous conditions are met.
Full code is below:
string dataset="";
if (System.Web.HttpContext.Current.Session["user"] != null)
{
if (name != null && carId != null)
{
using (SqlConnection con = new SqlConnection(st))
{
string getCar = "SELECT * FROM [Car] WHERE CarId = #carId";
SqlCommand cmd = new SqlCommand(getCarData, con);
cmd.Parameters.AddWithValue("#carId", carId);
using (cmd)
{
con.Open();
SqlDataReader data = cmd.ExecuteReader();
if (data.HasRows)
{
while (data.Read())
{
if (data["available"].ToString() == "0")
{
data.Close();
SqlCommand getParts = new SqlCommand("SELECT * FROM [CarCustomer] WHERE UserId = #UserId AND car=#carId", con);
getParts.Parameters.AddWithValue("#userId", System.Web.HttpContext.Current.Session["userId"]);
getParts.Parameters.AddWithValue("#carId", carId);
SqlDataReader grabRows = getParts.ExecuteReader();
if (grabRows.HasRows)
{
grabRows.Close();
SqlCommand updateTable = new SqlCommand("UPDATE [Table1] SET salesAmount=5 WHERE UserId=1", con);
updateTable.BeginExecuteReader();
}
else
{
grabRows.Close();
SqlCommand addToTable = new SqlCommand("INSERT INTO [Table1] (salesAmount) Values("1")", con);
addToTable.BeginExecuteReader();
}
dataset="good"
}
}
}
}
}
}
}
return dataset;
Instead of BeginExecuteReader command use SqlCommand.ExecuteNonQuery , because ExecuteNonQuery is used to perform query like insert,update and delete where as for Gettting data Read method is used.
one more thing BeginExecuteReadermethod is used to perfrom asncy read operation so if you dont want that than just use ExecuteReadermethod to get data.
Read SqlCommand.ExecuteNonQuery -
You can use the ExecuteNonQuery to perform catalog operations (for example, querying the structure of a database or creating database objects such as tables), or to change the data in a database without using a DataSet by executing UPDATE, INSERT, or DELETE statements.

return type of SqlDataReader method

I have a method inside a class, that contains SqlDataReader(it connects to a database table and retrieves a number of rows).
later i want to assign each record that SqlDataReader has, to asp labels . but i don't know what should be the return type of a method , so i can extract the values from it, and how to do that in code behind file.
here is the code;
public (???) displayCustoemrhShipOrder()
{
string htmlStr = string.Empty;
string sConnectionString = ConfigurationManager.ConnectionStrings["LGDB"].ToString();
SqlConnection SqlCOn = new SqlConnection(sConnectionString);
SqlCommand SqlCmd = new SqlCommand();
SqlCmd.Connection = SqlCOn;
SqlCmd.CommandText = "displayCustomerShipOrder";
SqlCmd.CommandType = CommandType.StoredProcedure;
SqlCOn.Open();
SqlCmd.Parameters.AddWithValue("ShipOrderID",shipOrderID);
SqlDataReader reader = SqlCmd.ExecuteReader();
while (reader.Read())
{
htmlStr = reader.GetInt32(0).ToString();
}
reader.Close();
SqlCOn.Close();
return(???)
}
In general, you should never return SqlDataReader to a layer outside of your database-access code. The reason behind this general principle is that SqlDataReader is a very "expensive" object that keeps an open connection to the database! So if you keep a SqlDataReader around, it's not so bad, but if you keep 10 lying around at any given time? what about 100 of them? 1000? It's a recipe for disaster.
So how do you close the connection to the database from a SqlDataReader? .NET has a very handy methods in the IDisposable interface called Dispose() that will take care of the cleanup for you. So your code might looks like
function getData()
{
// instantiate SqlDataReader from SqlCommand, call it "rdr"
rdr.Dispose();
}
But actually there's an issue with that code. What if your code throws an exception before it gets to Dispose()? It should really look like
function getData()
{
try{
// instantiate SqlDataReader from SqlCommand, call it "rdr"
}
catch(Exception){}
Finally{
rdr.Dispose();
}
}
That's very verbose! What if you don't want to type all that? Don't worry, .NET handled this for you as well. Do this:
public (???) displayCustoemrhShipOrder()
{
string htmlStr = string.Empty;
string sConnectionString = ConfigurationManager.ConnectionStrings["LGDB"].ToString();
using(SqlConnection SqlCOn = new SqlConnection(sConnectionString))
{
using(SqlCommand SqlCmd = new SqlCommand())
{
SqlCmd.Connection = SqlCOn;
SqlCmd.CommandText = "displayCustomerShipOrder";
SqlCmd.CommandType = CommandType.StoredProcedure;
SqlCOn.Open();
SqlCmd.Parameters.AddWithValue("ShipOrderID",shipOrderID);
using(SqlDataReader reader = SqlCmd.ExecuteReader())
while (reader.Read())
{
htmlStr = reader.GetInt32(0).ToString();
}
// reader.Close(); // this line becomes optional, Dispose() will call Close()
}
// SqlCOn.Close(); // this line becomes optional, Dispose() will call Close()
}
}
return(???)
}
This is all a roundabout way of saying that if you know you need to Dispose() and Close() the SqlDataReader, and that you cannot get data out of it once you do that, then you obviously should not return it to code what needs to work with the data (but not necessarily the database connection that it was taking up). I suggest using a DataTable class, you can read about it here:
.NET DataTable class
Also the method to convert to a DataTable is called DataTable.Load(SqlDatareader...
You can add each individual value to List<string> return it and use outside of the method.

Execute select query from code behind

How can i execute a SELECT query from my Code Behind file and then iterate through it?
I want to do something like this (just a simple pseudo example):
// SQL Server
var results = executeQuery("SELECT title, name FROM table");
foreach (var row in results)
{
string title = row.title;
string name = row.name;
}
How can i do this within code?
Something like this:
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader["OrderID"], reader["CustomerID"]));
}
}
}
Source: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx
The connectionString will vary depending on the Database product and the authentication mechanism used (Windows Auth, username/password, etc.). The example above assumes you are using SQL Server. For a complete list of different ConnectionStrings, go to http://www.connectionstrings.com/

Not able to insert update delete

I'm using Asp.net c# and MYSql as back-end. I'm updating a table,but table is not updating.There are only 3 columns in the table.
There is no exception when I'm executing the command object. But this returns 0 value from cmd.ExecuteNonQuery().
I debugged this and found cmd.Parameters are full with values. and if i manually run the update command in mysql it works fine.
the table is as follow
column -- Datatype
ShortText -- varchar
title -- varchar
id -- int
Please guide me...
int retVal = 0;
string shortText = ((TextBox)fmvwShortText.FindControl("txtShortText")).Text.Trim();
try
{
int id = Convert.ToInt32(((Label)fmvwShortText.FindControl("lblShrtTextID")).Text);
MySqlConnection con = new MySqlConnection(System.Configuration.ConfigurationManager.AppSettings["conn"]);
cmd = new MySqlCommand();
cmd.Connection = con;
cmd.CommandText = "UPDATE temp_posts SET ShortText=#shrtText WHERE id=#id AND Title=#title";
cmd.Parameters.Add("#shrtText", MySqlDbType.VarChar).Value = shortText;
cmd.Parameters.Add("#title", MySqlDbType.VarChar).Value =Session["EditTitle"].ToString();
cmd.Parameters.Add("#id", MySqlDbType.Int32).Value = id;
con.Open();
retVal = cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception e) { }
return retVal;
Is it possibly a casing issue with your Title parameter? I notice you are only updating if the ID & Title match exactly?
Also as a general rule of thumb, when using objects which implement IDisposable you should wrap them with a using statement, this will make sure your objects are always disposed (even on the result of an error)
using (var con = new MySqlConnection(...))
{
using (var cmd = new MySqlCommand(...))
{
....
}
}
First of all thank you every one who kept looking and tried their best to sort out this problem with me..
Finally got the solution.
In my code I used # in cmd.CommandText and in parameters.
But when I replace this # with ? both in cmd.CommandText and in parameters and used the cmd.ExecuteScalar(); this worked.
Actually Parameter names depend on the provider. When using the provider for
SQL Server, it should start with # (e.g. #param1). For Oracle
provider, it should start with a colon (...for e.g. aram1. For
OleDb provider, just a question mark (?) would work
Thank you everyone to contribute your best... many thanks
But i'm still left with a question that ExecuteScalar() is updating the records in the database? I am with no answer... looking for this.
Try this nt sure about code formating coz currently am not using ide frmwrk
int retVal = 0;
string shortText = ((TextBox)fmvwShortText.FindControl("txtShortText")).Text.Trim();
try
{
int id = Convert.ToInt32(((Label)fmvwShortText.FindControl("lblShrtTextID")).Text);
MySqlConnection con = new MySqlConnection(System.Configuration.ConfigurationManager.AppSettings["conn"]);
cmd = new MySqlCommand("UPDATE temp_posts SET ShortText='"+shortText+"' WHERE id='"+id+"' AND Title='"+Session["EditTitle"].ToString()+"'",con);
con.Open();
retVal = cmd.ExecuteNonQuery();
con.Close();
return retVal;
}
catch (Exception e) { }

Can you use 2 'using' statements for both sqlconnection and sqldatareader?

Can you use 2 'using' statements like:
using (SqlConnection ..)
{
using(SqlDataReader reader = new SqlDataReader())
{
}
}
I'm trying to do this put getting an error on the constructor of the SqlDataReader
SqlDataReader has no constructor. You are returned a datareader by calling the ExecuteReader method of a SqlCommand object.
e.g.
using (SqlConnection ..)
{
SqlCommand cmd = new SqlCommand(...);
using(SqlDataReader reader = cmd.ExecuteReader()))
{
}
}
You can and you can also format them without the extra brackets like so:
using (SqlConnection ..)
using(SqlDataReader reader = new SqlDataReader())
{
}
Which I do all the time to limit the amount of scope nesting.
You can't instantiate a SqlDataReader like that as mentioned above. Generally I see 2 levels of using blocks, but the inner one would be the command object, something like this:
using (var conn = new SqlConnection(...))
{
conn.Open();
using (var cmd = new SqlCommand(...))
{
var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
}

Resources