views:

648

answers:

7

I am working on a database application in C#. I had a requirement to display data on a table and I am now done with that. But my business logic is hardcoded to my code. Now I want to go ahead and use Stored procedures with my code. What are the modifications that I need to do. A simple list of steps would be enough :)

SqlConnection myConnection = new SqlConnection("user id=dbblabla;" + 
   "password=1234;server=localhost\\SQLEXPRESS;" + 
   "Trusted_Connection=yes;" + 
   "database=myDB; " + 
   "connection timeout=30");

try
{
 myConnection.Open();
} catch (SqlException excep){
 Console.WriteLine(excep.StackTrace);
}

String selectionQuery = "SELECT * FROM myTable";
SqlDataAdapter myAdapter = new SqlDataAdapter(selectionQuery,myConnection);

DataSet ds = new DataSet();
myAdapter.Fill(ds,"AllInfo");

dataGridSearchOutput.DataSource = ds.Tables["AllInfo"].DefaultView;

I started from creating a new SQL command but I am not sure I am using the correct way.

SqlCommand newCommand = new SqlCommand("SELECT * FROM PMInfo");
newCommand.CommandType = CommandType.StoredProcedure;
+1  A: 
SqlCommand newCommand = new SqlCommand("SELECT * FROM PMInfo");
newCommand.CommandType = CommandType.StoredProcedure;

This will not work correctly, because you are not using a store procedure, the above command should be called like this

SqlCommand newCommand = new SqlCommand("SELECT * FROM PMInfo");
newCommand.CommandType = CommandType.Text;

If you are calling a stored procedure, you would call it like this:

SqlCommand newCommand = new SqlCommand("spYourProcedure");
newCommand.CommandType = CommandType.StoredProcedure;

See here in the MSDN for more details, it will also go into using parameters

phsr
The same question applies to here as well. I have defined the SP in my DBMS.. i.e in MSSQL2005. So how the program know "spYourProcedure" is a stored procedure associated with myConnection? As far as I feel the sqlCommand will try to parse it as a SQL string..
Chathuranga Chandrasekara
@Chathuranga: setting the CommandType to "StoredProcedure" is how the SqlCommand object knows it's a stored procedure.
MusiGenesis
+6  A: 

Stored-Procedure

CREATE PROCEDURE addemp
     @eno int,
     @ename varchar(50),
     @edate datetime
AS
  declare @p int

  select @p=count(*) from emp
      where eno=@eno
  if @p=0
     begin
       insert into emp
         values (@eno,@ename,@edate)
     end        
    RETURN

C# code

    SqlConnection cn = new SqlConnection(@"conn_str");
    SqlCommand cmd = new SqlCommand("addemp", cn);
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.AddWithValue("@eno", 10);
    cmd.Parameters.AddWithValue("@ename", "Mr.Xyz");
    cmd.Parameters.AddWithValue("@edate", DateTime.Parse("1-1-2002"));

    cn.Open();
    cmd.ExecuteNonQuery();
    cn.Close();
adatapost
Could you elaborate on the performance difference between `AddWithValue` vs `Add("@eno", SqlDbType.Int); ["@eno"]=...`?
Crescent Fresh
crescentfresh, there is no performance difference.
Henk Holterman
I don't think there is a performance difference issue with AddWithValue. Both methods passed boxed value. Especially with varchar or char AddWithValue requires explicit conversion from nvarchar to varchar or char.
adatapost
I've been under the impression for at least a year now that the .NET layer needed to know the `SqlDbType` of the parameter before passing it on to Sql Server. This is an eye opener. So much more readable this way.
Crescent Fresh
Thanks buddy. I appreciate your knowledge.
adatapost
@crescentfresh: ADO.Net has never needed to know the SqlDbType of the parameter, going back at least 8 years. I always found that to be one of its big advantages.
MusiGenesis
A: 

This is not exactly an answer to your question, but in your case I would not bother with turning your queries into stored procedures, as it is potentially a lot of extra work with no real benefits. In days of yore, stored procedures in SQL Server were faster than so-called ad hoc SQL queries, because SQL Server could calculate and cache the execution plans for your queries. In modern versions of SQL Server, however, the database will cache the execution plan for each query after it has been run once, so after the initial execution of the ad hoc query it will be executed just as fast as a stored procedure.

Also, one real and major advantage of keeping your queries in your application code is that the queries will be under source control and versionable (assuming you're using source control, of course). It is possible to version stored procedures in SQL Server, but this is more work and people rarely do it.

Finally, moving your queries to stored procedures will mean rewriting substantial portions of your application code, since stored procedures are not accessed in the same way as ad hoc SQL queries. It might have made sense to write your application using stored procedures at the beginning, but it makes a lot less sense to convert your application to using stored procedures after you've already written it to use ad hoc SQL queries.

MusiGenesis
`[citation needed]` for your first paragraph.
Crescent Fresh
I am still at the beginning of DB layer codings so there is no overhead in migrating from static queries to SP. But according to your answer I feel 1 thing. Is there no advantage in using SPs? I don't have multiple applications that accesses the same database. So is there no harm in using the static SQL queries?
Chathuranga Chandrasekara
@crescentfresh: here you go: dictionary.reference.com/browse/Yore
MusiGenesis
+1 for the point about harder source control with stored procedures
ChrisF
@crescentfresh: since you were probably wanting a citation for my claim about stored procedures and cached execution plans (and not a definition for "days of yore"), here's a StackOverflow-appropriate link for you: http://www.codinghorror.com/blog/archives/000292.html
MusiGenesis
@Chathuranga: SPs are just a pain in the butt at this point, in my opinion. There is no harm in using ad hoc SQL queries, as long as the queries are *parameterized.* Code like this: [sqlQuery = "SELECT * FROM tblWhatever WHERE ID = " + intID + " AND NAME = '" + strName + "'"] is still very very bad.
MusiGenesis
SQL Server caches the execution plan for ad hoc queries on the basis of the text of the query, so if you're passing in queries that are different because they're manually constructed from variables each time, their execution will be slow. Also, you expose yourself to SQL injection this way.
MusiGenesis
@ MusiGenesis : In summary your idea is it is ok to use SQL queries until I take care of SQL Injection attacks.. And I didn't get your idea of Parameters... (The way of good coding). Can I have a small example??
Chathuranga Chandrasekara
@MultiGenesis: your comments re parameterized sql are also reflected in an excellent link on the page of the url you mentioned. Maybe the link belongs in the answer itself at this point.
Crescent Fresh
Using SP has several benefits. They are never slower, usually faster and they help organize access to your DB. They can also help to mitigate schema changes. I would only consider queries for small applications.
Henk Holterman
@crescentfresh: "MultiGenesis" is a new one - usually people type "MusicGenesis". :-) Which link? I didn't actually read the article - my statement about caching execution plans came from the textbook for the MS certification exam for SQL Server, which I don't have any more.
MusiGenesis
Wow. 2009, and still people are advocating ad-hoc SQL? Of course you're storing your procs in source control. Just like your DB change scripts and every other piece of code. Suggesting otherwise casts doubts on your knowledge in this area.And no, you're not *moving* ad-hoc sql to stored procs. You're writing them from the start, like you should. That's why your life is so much easier.
Jason Kester
@Henk: I would say they are almost *never* faster, and they do not help mitigate schema changes - if the schema changes, you would have to change the stored procedure *or* the ad hoc query either way. I'm not sure what you mean by "they help organize access to your DB".
MusiGenesis
I feel it's valid to answer the question; there are shops that mandate stored procs and disallow ad hoc queries in the production environment due to security concerns. SPs also can reduce duplication when the same query must be made from multiple environments (.NET code, Java code, and reporting software, say). This is a heated discussion - see in part http://stackoverflow.com/questions/15142/what-are-the-pros-and-cons-to-keeping-sql-in-stored-procs-versus-code
TrueWill
@Jason Kester : Your idea is "I hate ad-hoc SQL".. Isn't it? However I would like to see a answer here from you on points against the MusiGenesis's points :) It would be a nice discussion and I think I may have a lot to learn from that
Chathuranga Chandrasekara
@TrueWill : No best answer there. Can I assume that the answer is highest votes is the best answer?
Chathuranga Chandrasekara
@Jason: re-read the original question - he was specifically asking about moving ad-hoc sql to stored procs. I would suggest that your apparent inability to read casts doubts on *your* knowledge in this area, but a statement like that would be rude, and rude people suck.
MusiGenesis
@musi, indeed he was. As nice as it is to see that he's trying to improve the health of his codebase, my point is that he should never have got this far down the road of copy/pasting example code into the IDE.He's now at the first step of writing the abstractions he'll need to move quickly in the future. That's a good thing. With luck, by the time he starts his next project, his backend will be up to speed and he won't be tempted to take silly shortcuts like writing ad-hoc SQL in a .aspx.cs file.
Jason Kester
@Jason: well, you started off polite and then became rude again. As TrueWill's linked question shows clearly, there is by no means consensus on whether or not stored procedures are a good thing. If I had said something like "you should store your code in zip files on floppy disks instead of using source control", you might be justified in describing me as "silly" or in doubting my knowledge in this area. Grow up, dude.
MusiGenesis
Sprocs are often mandated by those that own the database. They use them to lock down write access to their data tables, and as protecting the data is their primary role, sprocs serve them well.The only time I would not use them, is if I was using something link Entity Framework to handle my updates. This of course allows you to skip the creation of the most boring code in most applications, the code that calls the sprocs.I see no advantage in writing ad hoc queries for updating the database. I am not saying that doing so is evil by any means. If they are properly formed they work.
Chrisb
+2  A: 

You just need to specify the stored procedure name to the SqlCommand constructor and set the CommandType to CommandType.StoredProcedure. Also it is a good practice to wrap disposable objects in using block. SqlConnection, SqlCommand and SqlAdapter are disposable objects. Here is a modified code.

string connectionString = "user id=dbblabla;" + 
                        "password=1234;server=localhost\\SQLEXPRESS;" + 
                        "Trusted_Connection=yes;" + 
                        "database=myDB; " + 
                        "connection timeout=30";
DataSet ds = new DataSet();
using(SqlConnection myConnection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand("yourprocedure", myConnection))
{
    SqlDataAdapter myAdapter = new SqlDataAdapter();
    myAdapter.SelectCommand = command;
    myAdapter.Fill(ds,"AllInfo");
}
dataGridSearchOutput.DataSource = ds.Tables["AllInfo"].DefaultView;
Appu
+5  A: 

stored procedure

CREATE PROCEDURE  procedure 

AS
BEGIN

    SET NOCOUNT ON;
    SELECT field1,field2 from tbl
END
GO

code

using(SqlConnection con = new SqlConnection("user id=dbblabla;password=1234;server=localhost\\SQLEXPRESS; database=myDB; connection timeout=30"))
        {
            SqlCommand cmd = new SqlCommand("procedure",con);
            cmd.CommandType= System.Data.CommandType.StoredProcedure;
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            da.Fill(dt);
            dataGridSearchOutput.DataSource = dt;           

        }

why i used using is check this link

anishmarokey
A: 

For what it's worth, you'll want to go a long way beyond simply wrapping your stored procedures in the codebehind. For some insight into how far, check out this article:

Code on the Road: ExampleCode != ProductionCode

Ad-hoc SQL is one of the simplest to fix, yet most prevalent forms of code duplication that we come across as developers. Even just a few minutes of thinking about how to organize your database interaction will pay off in spades in the form of maintainability and development pace.

Jason Kester
Ad-hoc SQL != code duplication. You can put a query in one place in your code (in these things called "functions"), just like you can duplicate a query multiple times in multiple stored procedures (in databases I've inherited from other developers, this is an incredibly common problem, much more common than query duplication in application code).
MusiGenesis
+2  A: 

I don’t understand why people forget they are in an object oriented language when it comes to the data access code. You should not be writing the same code over and over again. First, you should have a base class that is used in all of your projects. This base class should take care of the connection string, logging exceptions, etc. I wrote one years ago and haven’t changed it much since.

Look at the following for samples that would be in this base class:

protected SqlCommand GetNewCmd()
{
    SqlCommand objCmd = new SqlCommand();
    objCmd.Connection = new SqlConnection(this.ConnString);
    objCmd.CommandType = CommandType.StoredProcedure;
    return objCmd;

}

protected SqlCommand GetNewCmd(string CmdText)
{
    SqlCommand objCmd = new SqlCommand(CmdText, 
                             new SqlConnection(this.ConnString));
    objCmd.CommandType = CommandType.StoredProcedure;
    return objCmd;
}

protected DataTable GetTable(SqlCommand objCmd)
{
    DataTable dt = new DataTable();
    SqlDataAdapter da = new SqlDataAdapter();

    try
    {
        da.SelectCommand = objCmd;
        da.Fill(dt);

        dt.DefaultView.AllowNew = false;
    }
    catch (Exception ex)
    {
        LogException(ex);
        throw;
    }
    finally
    {
        Close(objCmd);
        da.Dispose();
        da = null;

    }

    return dt;

}

We have GetTable(), GetDataSet(), ExecuteScalarInt(), ExecuteScalarGuid(), etc. and a bunch of overloads for each.

So these are in my base class and I inherit from this class to do my project specific work. But now this is greatly simplified like these examples:

public DataTable GetStages(int id)
{
    SqlCommand cmd = GetNewCmd("dbo.GetStages");
    cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;
    return GetTable(cmd);
}

public void DeleteStage(int id)
{
    SqlCommand cmd = GetNewCmd("dbo.DeleteStage");
    cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;
    ExecuteNonQuery(cmd);
}

As a side benefit, I can script out this code based on the stored proc. Here is the code to do that. So it saves me a lot of typing especially when there are a lot of parameters.

Finally, using other object oriented techniques I get my code down to the following:

GridView1.DataSource = cApp.DB.GetStages(id);
GridView1.DataBind();

(Most of the time there is a business object in the middle of that, but you get the idea.) All the connection string, exception logging, etc is encapsulated in that 1 line.

Another side benefit is that your base class can get way more involved then you ever would if you are copying code every time. For example, we log exceptions to a database table. Only if that fails does it then log it to a text file. This extensive logic is fine if it lives in one place in the base class, but its not something you are going to want to copy and paste all over your project.

This also make it easy to incorporated some best practices such as opening the connection as late as possible and closing it as soon as possible.

JBrooks
Longest. Answer. Ever.
bzlm