over the past week or so I've been building an ASP site that connects to a Sql-Server 2008 database. I've never used Stored procedures and I was wondering if anyone could give me some guidance on how to create and how to use them within an ASP method. I'm trying to make the code of the website as simple and elegant as possible. Here's the code I'm trying to change into a stored procedure:
private void ExecuteInsert(string name, string type)
{
SqlConnection conn = new SqlConnection(GetConnectionStringHM());
string sql = "INSERT INTO tblSoftwareTitles (SoftwareName, SoftwareType) VALUES "
+"(#SoftwareName,#SoftwareSystemType)";
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlParameter[] param = new SqlParameter[2];
//param[0] = new SqlParameter("#SoftwareID);
param[0] = new SqlParameter("#SoftwareName", SqlDbType.NVarChar, 200);
param[1] = new SqlParameter("#SoftwareType", SqlDbType.Int);
param[0].Value = name;
param[1].Value = type;
for (int i= 0; i < param.Length; i++)
{
cmd.Parameters.Add(param[i]);
}
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg ="Insert Error:";
msg += ex.Message;
throw new Exception(msg);
}
finally
{
conn.Close();
}
}
This is just a Simple insert that takes two parameters from an entry form and inserts them into the database. Any Help with this would be much appreciated as I feel it would be a useful thing to know later on down the line. Thanks in advance!
You should look in to MSDN basics: http://msdn.microsoft.com/en-us/library/bb896274.aspx
You don't need to complicate things using for loop.
try
{
sqlConnection = new SqlConnection(dbConnectionString);
SqlCommand command = new SqlCommand(sql, sqlConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#SoftwareName", SqlDbType.NVarChar, 200).Value = SoftwareNameHere;
command.Parameters.Add("#SoftwareType", SqlDbType.Int).Value = SoftwareTypeHere;
sqlConnection.Open();
return command.ExecuteNonQuery();
}
catch (SqlException ex)
{
Console.WriteLine("SQL Error" + ex.Message.ToString());
return 0;
}
finally
{
conn.Close();
}
If you are using .NET 3.5 or above, you can use the USING code block which takes care of the disposal of your resources. I am not entirely sure, but from what I remember this was introduced with .NET 3.5 to replace Try/Finally code block (which required developers to dispose the resources like connection object manually through code).
using (SqlConnection con = new SqlConnection { dbConnectionString })
{
con.Open();
try
{
using (SqlCommand command = new SqlCommand { CommandType = CommandType.StoredProcedure, Connection = con, CommandTimeout = 300, CommandText = "sp_Test" })
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#SoftwareName", SqlDbType.NVarChar, 200).Value = SoftwareNameHere;
command.Parameters.Add("#SoftwareType", SqlDbType.Int).Value = SoftwareTypeHere;
command.ExecuteNonQuery();
}
}
catch(SqlException ex)
{
//ex.ToString message here;
}
}
The answer you're looking for is at this SO post...
https://stackoverflow.com/a/4561443/1246574
The one thing I would improve upon for the accepted answer in that post, is the example in that answer doesn't use any USING statements. It would be better to have the connection and command within USING statements so they are automatically disposed.
Another approach would be to use the Microsoft Enterprise Library for interacting with your SQL Server DB. I think it's easier than using plain old SqlConnection and SqlCommand.
Since your code already uses parameters, you are 90% of the way there. All you have to do is:
Put the insert statement into a stored procedure, keeping the same parameter definitions as the dynamic statement.
Change CommandType.Text to CommandType.StoredProcedure
Change the command text to be just the name of the stored procedure.
Having done some reading on the subject I've come across some useful articles that really do question my need for stored procedures.
This article gives a good Viewpoint on how stored procedures can be more of a hassle than a help and are quite clunky and tedious in terms of coding, debugging ad error reporting.
http://www.codinghorror.com/blog/2004/10/who-needs-stored-procedures-anyways.html
And this article (linked in the one above) gives a good explanation on parametrized, explaining why they are necessary to reduce the risk of sql injections and also raises the point that these parametrized queries are cached in a similar way to procedures, giving them comparable performance gains
http://www.uberasp.net/getarticle.aspx?id=46
I feel that In my situation keeping parametrized sql Queries coded into my ASP pages will be the smartest move as these pages will be stored on a server and accessed by clients. I imagine if this were an application installed on several client machines hard coding the SQL wouldn't be a desirable option and so Stored procedures would be the best way to go (to my knowledge)
A follow Up to Stored procedures verses Parametrized sql can be found here with different links to each side of the argument if those are interested.
http://www.codinghorror.com/blog/2005/05/stored-procedures-vs-ad-hoc-sql.html
Hope this little answer helps out anyone else considering using stored procedures over parametrized SQL and vice-versa
Related
I set up a using block for a TransactionScope at the beginning of an ASP.NET action. Somewhere w/i the block I execute a function that both creates a using block for a SqlCommand and w/i that a using block for my SqlConnection.
The blocks for the command and connection open and close as the function is re-used but all w/i the TransactionScope using block. Eventually I call scope.Complete() and when leaving the TransactionScope using block I get an exception saying that no transaction was started that can be committed. In debugging I find that in fact all database calls are just happening w/o a transaction.
Based off the documentation its seeming like the generation of the TransactionScope should be the generation of the transaction, OR, at least that the first time I open any database connection that a transaction should begin because it's w/i the transaction scope block. However this is not the case and I'm unsure why this is.
I actually had this working fine at one point and then all of a sudden, it was not working. So there's something that I did that caused it but I have no idea what it was as the section this was implemented in was completed long ago.
Here's some code:
Starting the transactionScope
using (TransactionScope transactionScope = new TransactionScope())
{
try
{
LegacyDataManager.Start();
//*******************Replace W/ Controller Logic*********************
ViewBag.Message = "Finish";
...
...
...
LegacyDataManager.Commit();
transactionScope.Complete();
}
finally
{
LegacyDataManager.Stop();
}
}
Call to code that executes database update
var theApproval = LegacyDataManager.PrepareForUpdate(Constants.ObjectApproval, row["objectInstance"].ToString(), row["sourceServer"].ToString());
theApproval.write("approvalaction", Request.Form[val].ToString().Substring(0, 1));
theApproval.write("approvaldate", Data_Legacy.getAodDateTimeNow());
theApproval.saveObject();
The database query execution
Data.executeSP("sp_Object_InsertData", SearchNew.generateSQLParameterString("ObjectType", "ObjectInstance", "Parameter", "ParameterValue", "SourceServer"),
SearchNew.generateSQLParameterString(
ObjectType,
ObjectInstance.ToString(),
theNametext,
Regex.Replace(thetheVal, #"\'", "\'\'").Trim(),
SourceServer));
public static DataTable executeSP(string storedProc, SqlParameter[] parms = null, bool gatherParams = true, int commandTimeout = 0)
{
using (SqlCommand cmd = new SqlCommand())
{
if (commandTimeout != 0)
{
cmd.CommandTimeout = commandTimeout;
}
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = storedProc;
handleParameters(cmd.Parameters, storedProc, parms, gatherParams);
using (SqlConnection conn = Data.getConnection("AOD"))
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
var da = new SqlDataAdapter();
var dt = new DataTable();
da.SelectCommand = cmd;
da.Fill(dt);
return dt;
}
}
}
Thanks for any suggestions in advance.
The good news is that this can just be removed but the bad news is that it creates an annoying programming environment where the XML data files this system is based don't get updated during an error but the updated SQL data that is mirrored out to is retained... Don't ask why that's how it is... it just is.
Apparently I had added a try/catch block around a function that ran a Stored procedure because the data being passed in would sometimes need the function and sometimes not (and thus fail, hence the try catch). Unfortunately when the db call failed the transaction associated w/ the TransactionScope was dropped and the try catch kept the program going.
I removed the the try catch block and replaced it w/ a check on the data passed into the function before determining whether or not to execute the Stored Procedure and now it is once again operating properly.
TL;DR - Check to see if any database calls are failing w/i the transactionScope as it might lead to dropping of the transaction.
I have written a code in ASP.NET to fetch data from Oracle database. The code returns data from locally hosted Oracle DB but when I am pointing towards the remote OracleDB, nothing comes. However, if I run same query on the remote DB using SQL Developer Tool, it works fine.
I have debugged my code for right SQL statement and it is absolutely correct.
Following is my code snippet
using (Oracle.DataAccess.Client.OracleConnection con = new
Oracle.DataAccess.Client.OracleConnection())
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["ca_eFormsVSED"].ConnectionString;
con.Open();
// query for fetch username and market
String sql = "a valid query"
Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand(sql, con);
cmd.CommandType = CommandType.Text;
if (con.State == ConnectionState.Open)
{
Oracle.DataAccess.Client.OracleDataReader dr = cmd.ExecuteReader();
}
if (dr.Read())
{
//Do Something
}
}
Please suggest how to make it work.
I got the solution of this problem and it may help some one else. If you are 100% sure that code is correct and current SQL statement returns data from database, then check carefully your database tables have dependency or not. Remove existing tables and import new data again and it works fine for me.
I am very new to ASP.NET. I have Visual Studio Express 2013 and MSSql Server that contains a bunch of databases. I watching a few tutorials about MVC/Entity framework to retrieve data from a table and display it. However, it is using Linq to SQL which I am not familiar with. All I need is to write a sql query to combine information in two tables and display it in the view. I could not find this simple tutorial on the internet. Can anyone give me a hint please?
To run a simple query you need to create a connection to the database like following:
var connection = new SqlConnection("your connecting string");
Once you have that you can connect to database and query using something called SqlCommand like following:
using (connection)
{
SqlCommand command = new SqlCommand(
"SELECT CategoryID, CategoryName FROM Categories;",
connection);
connection.Open();
//fetches the data by executing the command
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
//You can process data here , read it from reader and process it
// the index 0 and 1 indicate your query columns
var somedata = reader.GetInt32(0) + reader.GetString(1));
}
}
else
{
//no data returned from query
}
reader.Close();
}
Can anyone share a link to sample (ASP).Net code that uses the new Oracle Data Provider.Net library?
I have code a web application code that uses the System.Data.OracleClient classes and want to migrate to the new Oracle Data Provider for .Net.
Thanks
Your code might look as any standard ADO.NET code and you will be using an OracleConnection:
var connectionString = "Data Source=ORCL;User Id=user;Password=pwd;";
using (var conn = new OracleConnection(connectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT name FROM mytable";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string name = reader.GetString(0);
// TODO: process the results here
}
}
}
There is no real difference in how they are used, unless you are doing weird stuff with In/Out parameters or cursors.
The difference that you would see in your code is that the namespace will change to Oracle.DataAccess. I believe that most of the type-names stayed the same.
I was recently advocating to a colleague that we replace some C# code that uses the sqlcmd command line utility with a SqlDataReader. The old code uses:
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + sqlCmd); wher sqlCmd is something like
"sqlcmd -S " + serverName + " -y 0 -h-1 -Q " + "\"" + "USE [" + database + "]" + ";+ txtQuery.Text +"\"";\
The results are then parsed using regular expressions. I argued that using a SQLDataReader woud be more in line with industry practices, easier to debug and maintain and probably faster. However, the SQLDataReader approach is at least the same speed and quite possibly slower. I believe I'm doing everything correctly with SQLDataReader. The code is:
using (SqlConnection connection =
new SqlConnection())
{
try
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
connection.ConnectionString = builder.ToString(); ;
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// do stuff w/ reader
reader.Close();
}
catch (Exception ex)
{
outputMessage += (ex.Message);
}
}
I've used System.Diagnostics.Stopwatch to time both approaches and the command line utility (called from C# code) does seem faster (20-40%?). The SqlDataReader has the neat feature that when the same code is called again, it's lightening fast, but for this application we don't anticipate that.
I have already done some research on this problem. I note that the command line utility sqlcmd uses OLE DB technology to hit the database. Is that faster than ADO.NET? I'm really suprised, especially since the command line utility approach involves starting up a process. I really thought it would be slower.
Any thoughts?
Thanks,
Dave
I think SqlDataReader is slower than sqlcmd because making a SqlDataReader not only fetches the data but also gets the database schema info, and the sqlcmd gets the data only.
You can get a column name with a datareader like this:
for (int i = 0; i < reader.FieldCount; i++)
{
Console.WriteLine(reader.GetName(i));
}
Sometimes performance is not important, security is more important.
But I don't know which is more secure, maybe SqlDataReader is.
I am a Chinese, so maybe my word is incorrect for the grammer, sorry.