Using many sql connection in one code? - asp.net

I have an ASP.NET web application which is connected to SQL Server.
I have used three connections for each SQL operation. It works very well, however I think this is not an efficient way to do things - can this be written better than it is?
public partial class Home : System.Web.UI.Page
{
SqlConnection co = new SqlConnection(ConfigurationManager.ConnectionStrings["TextConnectionString"].ConnectionString);
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["TextConnectionString"].ConnectionString);
SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["TextConnectionString"].ConnectionString);
protected void Button1_Click(object sender, EventArgs e)
{
using (co)
{
co.Open();
SqlCommand cm = co.CreateCommand();
cm.CommandText = "select...";
cm.ExecuteNonQuery();
}
co.Close();
using (con)
{
con.Open();
SqlCommand cmv = con.CreateCommand();
cmv.CommandText = "insert...";
cmv.ExecuteNonQuery();
}
con.Close();
using (con2)
{
con2.Open();
SqlCommand cmf = con2.CreateCommand();
cmf.CommandText = "delete from...";
cmf.ExecuteNonQuery();
}
con2.Close();
}
}

SqlConnection co = new SqlConnection(ConfigurationManager.ConnectionStrings["TextConnectionString"].ConnectionString);
protected void Button1_Click(object sender, EventArgs e)
{
using (co)
{
co.Open();
SqlCommand cm = co.CreateCommand();
cm.CommandText = "select...";
cm.CommandText += " insert...";
cm.CommandText += " delete from...";
cm.ExecuteNonQuery();
}
co.Close();
}
you can use like this.

You're using the same connection string for each connection? Why do you need three connections? Why not just open and close the same one?
As long as the connection string is the same, you only need one connection.

In general you should prefer to create and open a connection object as close to where you make use of it as possible, and dispose of it as soon as possible afterwards (preferably by making use of a using statement). Connection pooling will take care of ensuring you only actually create a limited number of real connections to the server, despite the large number of SqlConnection objects your code may seem to create.
Within a single method, however, it is reasonable to use a single connection object:
public partial class Home : System.Web.UI.Page
{
string connString = ConfigurationManager.ConnectionStrings["TextConnectionString"].ConnectionString;
protected void Button1_Click(object sender, EventArgs e)
{
using (SqlConnection co = new SqlConnection(connString))
{
co.Open();
using(SqlCommand cm = co.CreateCommand())
{
cm.CommandText = "select...";
cm.ExecuteNonQuery();
}
using(SqlCommand cmv = co.CreateCommand())
{
cmv.CommandText = "insert...";
cmv.ExecuteNonQuery();
}
using(SqlCommand cmf = co.CreateCommand())
{
cmf.CommandText = "delete from...";
cmf.ExecuteNonQuery();
}
}
}
}
(You don't need to explicitly close the connection object, the Dispose (within the using is equivalent)

No use declaring/creating multiple connections when you would be using only one at a time. You can do with just one.
Declare variable as close as possible to its first use, and with minimum scope manageable.
Make things modular and reusable as far as possible.
No need to explicitly close the connection, since the IDisposable interface implementation (and using block) does it anyways. But there is no harm in explicitly closing it.
protected void Button1_Click(object sender, EventArgs e)
{
ExecuteNonQuery("select...", null); // why??
ExecuteNonQuery("insert...", null);
ExecuteNonQuery("delete from...", null);
}
protected void ExecuteNonQuery(string query, SqlParameter[] parameters)
{
using (SqlConnection co = new SqlConnection(ConfigurationManager.ConnectionStrings["TextConnectionString"].ConnectionString))
{
co.Open();
SqlCommand cm = co.CreateCommand();
cm.CommandText = query;
if (parameters != null) cm.Parameters.AddRange(parameters);
cm.ExecuteNonQuery();
}
}

You can also try this.
SqlConnection co = new SqlConnection(ConfigurationManager.ConnectionStrings["TextConnectionString"].ConnectionString);
protected void Button1_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(" Select statement.. ");
sb.AppendLine(" Insert statement ");
sb.AppendLine(" delete statement ");
using (co)
{
co.Open();
SqlCommand cm = co.CreateCommand();
cm.CommandText = sb.Tostring();
cm.ExecuteNonQuery();
}
co.Close();
}

Related

Filtering Web Forms GridView based on DatePicker not returning data

I have a web form with a gridview and two datepickers and a submit to submit the new query with the datetime constraints. to be the start and end dates to filter the data. The data loads fine without the data and when the submit button with the chosen dates is clicked, nothing happens. I wonder if the filtered data isn't being bound properly(I'm new to web forms and gridview.)
Here is the codebehind for the page:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindDataToGridView();
}
protected void dashboard_RowEditing(object sender, GridViewEditEventArgs e)
{
gridErrors.Text = string.Empty;
dashboard.EditIndex = e.NewEditIndex;
BindDataToGridView();
}
protected void dashboard_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
dashboard.EditIndex = -1;
BindDataToGridView();
}
protected void dashboard_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
dashboard.PageIndex = e.NewPageIndex;
BindDataToGridView();
}
protected void dashboard_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
gridErrors.Text = string.Empty;
GridViewRow tabRow = (GridViewRow)dashboard.Rows[e.RowIndex];
HiddenField hdnTabId = (HiddenField)tabRow.FindControl("hdnTabId");
TextBox TxtName = (TextBox)tabRow.Cells[1].Controls[0];
}
protected void button1_Click(object sender, EventArgs e)
{
var start = startDate.Text;
var startTime = DateTime.Parse(start);
var sqlStart = startTime.ToString("yyyy-MM-dd");
var end = endDate.Text;
var endTime = DateTime.Parse(end);
var sqlEnd = endTime.ToString("yyyy-MM-dd");
string sqlQuery = "SELECT TOP(100) TabID, TabName, Title, CreatedOnDate, TabPath From TableName " +
"where CreatedOnDate >= " + sqlStart + " and CreatedOnDate <= " + sqlEnd + " Order By TabName";
BindDataToGridView(sqlQuery);
}
public void BindDataToGridView(string sqlQuery =
"SELECT TOP(100) TabID, TabName, Title, CreatedOnDate, TabPath From TableName Order By TabName")
{
var connectionFromConfig = WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
using (SqlConnection db = new SqlConnection(connectionFromConfig))
{
try
{
db.Open();
SqlCommand command = new SqlCommand(sqlQuery, db);
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
if (dataSet.Tables[0].Rows.Count > 0)
{
dashboard.DataSource = dataSet;
dashboard.DataBind();
}
}
catch (SqlException ex)
{
gridErrors.Text = ex.Message;
}
finally
{
db.Close();
db.Dispose();
}
}
}
OnPageIndexChanging Method
protected void dashboard_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
dashboard.PageIndex = e.NewPageIndex;
BindDataToGridView();
}
ok, you found the issue (missing quotes). But, at the end of the day?
Yes, everyone will come pile in and note how "when" taking user input, you don't want to concatenate into the sql (too high risk for sql injection).
However, JUST telling you not to concatenate parameters don't help UNLESS we ALSO give you a nice design approach. Looking at your code, you did a GREAT idea to have one grid view load routine. And you ALSO want with great ease to pass sql to that one routine. However, that great idea + goal conflicts with using strong typed parameters.
So, lets kill two birds with one stone here.
and find that using parameters is often LESS code over all then a long messy sql string, which is prone to errors (quite much why you had to post here).
And for numbers - no quotes, for strings - yes, and for dates, again yes. So that's an extra developer workload. And that long messy string is HARD to write, debug, and manage.
So, I suggest this code:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindDataToGridView();
}
void BindDataToGridView(SqlCommand cmdSQL = null)
{
// default sql
if (cmdSQL is null)
{
cmdSQL = new
SqlCommand("SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName Order By TabName");
}
using (cmdSQL)
{
cmdSQL.Connection = new SqlConnection(conString);
cmdSQL.Connection.Open();
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
dashboard.DataSource = rst;
dashboard.DataBind();
}
}
note several things:
We did NOT have to create a separate connection object - sqlcommand has one!!
(and since we did not create a separate connection object, then disposing of the sql command takes care of that with our using block!!!
We did not need a separate datatable/dataset, and we did NOT need a data adaptor, and we did NOT need a reader either!! (sql command object has a reader too!!!).
So, now we can call our load grid without a parameter.
But, for the case WHEN we want to pass sql with parameters? Then we can do this:
{
string sqlQuery
= "SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName " +
"WHERE CreatedOnDate >= #Start AND CreatedOnDate <= #End ORDER By TabName";
SqlCommand cmdSQL = new SqlCommand(sqlQuery);
cmdSQL.Parameters.Add("#Start", SqlDbType.Date).Value = startDate.Text;
cmdSQL.Parameters.Add("#End", SqlDbType.Date).Value = endDate.Text;
BindDataToGridView(cmdSQL);
}
So, in fact, we can have parameters, we can have less code. We can have easy to read SQL, and we can pass the cmd SQL to that one routine.
So it NOT ONLY the suggesting to not concatenate strings, but with the right approach, we don't have to, we get strong data type conversion, and less code, and even less chances of errors in that code.
Also, check if the sql server column is a date, or datetime. If it is datetime, then specify that data type in the query parameter.
Also, you can droop the TOP clause - it only required when creating a SQL view which in theory does not support a sorted output. But for raw sql, then you can drop the TOP clause.
I needed to add single quotes before and after the sqlStart and sqlEnd variables for Sql Server to use the values with comparison operators.

Aspx and connecting to a access database on a share

Im trying to make a aspx application that connects to a access database on a share.
the path is correct, when i copy paste it in a run screen it opens a database right away.
The weird thing is that the exception that im getting is this, however the database is not a mdb and not in that location either.(it was dutch I translated it, might not be 100% correct translation):
Cant find file C:\Program Files (x86)\IIS Express\dbo.mdb
This is my code:
The exception is fired on the ExecuteReader
namespace AssetDB
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btn_zoek_Click(object sender, EventArgs e)
{
if (txt_name.Text.Length < 4)
return;
using (OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\netwerk\data\TeamFolders\ICT\Asset Database\_Backend\Assets_be.accdb; "))
using (OleDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "Select * from dbo.Bruikleen_Laptops where Laptop_id = #id";
cmd.Parameters.AddWithValue("#id", txt_name.Text);
conn.Open();
using (OleDbDataReader r = cmd.ExecuteReader())
while(r.Read())
{
drop_gevonden.Items.Add(r["Laptop_id"].ToString());
}
conn.Close();
}
}
}
}

update query is not working in ASP.NET web application

using System.Data.SqlClient;
using System.Data.Sql;
public partial class _Default : System.Web.UI.Page
{
SqlConnection con = new SqlConnection(#"Data Source=GAGAN-PC\SQLEXPRESS;Initial Catalog=update_test;Integrated Security=True");
SqlCommand cmd;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void delete_button_Click(object sender, EventArgs e)
{
con.Open();
cmd = new SqlCommand("delete from update_delete where id like'"+TextBox1.Text+"'",con);
cmd.ExecuteNonQuery();
Response.Write("Control reached.");
con.Close();
Response.Write("Data successfully deleted.");
}
protected void update_button_Click(object sender, EventArgs e)
{
con.Open();
cmd = new SqlCommand("update update_delete set password ='"+TextBox3.Text+"' where id like'"+TextBox2+"'", con);
cmd.ExecuteNonQuery();
Response.Write("Control reached.");
con.Close();
Response.Write("Data successfully Updated.");
}
}
I am trying to implement update query but there is a little problem in it. I have used SQL Server as database and update_delete is a table in which there are 3 columns id,sname,password and I am trying to update password with respect to id.
Problem is when I click on update button control reaches cmd.ExecuteNonQuery(); no error is displayed. but updating is not taking place. what should I do. Please Please Please help me. Thanks in advance. :) :)
I'm just guessing here - if Id is a numeric datatype, then you cannot use LIKE with it.
Also: please use using()... blocks to ensure proper disposal and use parametrized queries to avoid SQL Injection attacks.
Write your UPDATE command like this:
protected void update_button_Click(object sender, EventArgs e)
{
// get the values to use
string idValue = Convert.ToInt32(TextBox3.Text.Trim());
string password = TextBox2.Text.Trim();
// define the query text with *parameters* !
string updateQuery = "update update_delete set password = #password where id = #ID";
// put things like SqlConnection and SqlCommand into "using()...." blocks
using (SqlCommand updCmd = new SqlCommand(updateQuery, con))
{
// define parameters and their values
updCmd.Parameters.Add("#password", SqlDbType.VarChar, 50).Value = password;
updCmd.Parameters.Add("#ID", SqlDbType.Int).Value = idValue;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Response.Write("Data successfully Updated.");
}
}
I suppose you get an Exception. I would kindly suggest to catch your exception and tell us the message... You can catch the exception using the debugger or a try-catch clause.
If you don't get an exception and "Control reached" message is displayed, you would have to use the formed SQL string to use it directly in SQL Server and see if there is a mistake in the SQL statement. I suppose that you somehow form an invalid SQL statement (eg using a non-existing ID).
Hope I helped!

How to save Video file in DB?

I have a task to insert Video in DB and display it by Html5 video control. I did my code well and the video saved well in DB but when I tried to play the video it doesn't and when I checked my code I found that the video saved in DB with this path ~/res/Files/. When I
removed the ~/ as the path will be res/Files/ it worked well. How can I solve this issue?
protected void btnSubmit_Click(object sender, ImageClickEventArgs e)
{
btier.AddObject("~/res/Files/" + FUFile.FileName);
FUFile.SaveAs(Server.MapPath("~/res/Files/" + FUFile.FileName));
}
The reason being, you are passing the path as a string parameter to your method AddObject and to MapPath. Hence the path will remain "~/res/..." instead of resolving to the application root.
You have to first resolve the root and then save that path. One safe option is to use VirtualPathUtility. Something like this:
tempVar = VirtualPathUtility.ToAbsolute("~/res/Files/" + FUFile.FileName);
btier.AddObject(tempVar);
FUFile.SaveAs(Server.MapPath(tempVar));
Where tempVar is a string variable.
protected void btnUpload_Click(object sender, EventArgs e)
{
using (BinaryReader br = new BinaryReader(FileUpload1.PostedFile.InputStream))
{
byte[] bytes = br.ReadBytes((int)FileUpload1.PostedFile.InputStream.Length);
string strConnString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "insert into tblFiles(Name, ContentType, Data) values (#Name, #ContentType, #Data)";
cmd.Parameters.AddWithValue("#Name", Path.GetFileName(FileUpload1.PostedFile.FileName));
cmd.Parameters.AddWithValue("#ContentType", "video/mp4");
cmd.Parameters.AddWithValue("#Data", bytes);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
Response.Redirect(Request.Url.AbsoluteUri);
}
Complete step by step tutorial:
http://www.aspsnippets.com/Articles/Upload-Save-Retrieve-and-Play-MP4-Video-files-with-live-streaming-from-Database-in-ASPNet-using-C-and-VBNet.aspx

Execute Query from another function

I want to execute a query on a button click event.
But that query is written in another function.
Here is my code, and it's not working. What is my problem?
namespace MCE_Member_Registration
{
public partial class registration_form_view : System.Web.UI.Page
{
SqlConnection conn = new SqlConnection("ConnectionString");
SqlCommand cmd;
protected void Page_Load(object sender, EventArgs e)
{
createform();
}
protected void createform() {
NameValueCollection nvc = Request.Form;
surname.Text = nvc["txt_surname"];
cmd.CommandText = "Insert into mce_applicants_information values(N'" + nvc["txt_surname"] + "')";
}
protected void confirm_Click(object sender, EventArgs e)
{
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
I'm not sure if this solves your problem. But if you really need another method to create your command, let it return it.
protected SqlCommand GetCommand()
{
SqlCommand cmd = new SqlCommand("Insert into blahblah values(blahblah)", connection);
return cmd;
}
protected void Button1_Click() {
connection.Open();
GetCommand().ExecuteNonQuery();
connection.Close();
}
Note that this is not best-practise due to several reasons. The connection should be closed even if an exception occured so use using statement instead. But that would be a problem in this approach since the connection is a field.
So i would prefer the all-in-one method approach which also uses parameters tro prevent sql-injection attacks:
protected void Button1_Click()
{
ExecuteBlahBlahCommand("blahblah");
}
private void ExecuteBlahBlahCommand(string blaColumnVal)
{
const string sql = "Insert into blahblah values(#blaColumn)";
using (var con = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.AddWithValue("#blaColumn", blaColumnVal);
con.Open();
cmd.ExecuteNonQuery();
}
}
I suggest you to use CommandText property and not contructor, because instance of cmd is created before this code, so you adjust your property
protected void CreateQuery() {
cmd.CommandText = "Insert into blahblah values(blahblah)";
}
protected void Button1_Click() {
connection.Open();
CreateQuery();
cmd.ExecuteNonQuery();
connection.Close();
}
Answering the question itself - Any variable you declare inside a function cannot be seen outside that function. You need to declare the SqlCommand in the correct scope...
For instance:
SqlCommand cmd;
protected void CreateQuery()
{
cmd = new SqlCommand("Insert into blahblah values(blahblah),connection)";
}
protected void Button1_Click()
{
CreateQuery();
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
This will declare the variable in the class level, and be accessible to all other methods in that class.
I'll just mention that #Tim Schmelter's answer is a good solution that might better suit your needs.

Resources