Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « 2010 Goals: 4th Quarter/Year-End ReviewHow to move datafiles to a new drive in SQL Server »
    comments

    I was recently asked for some help with a very strange situation involving SQL Server and a .NET application using SqlCommand calls. It was thought to be a problem with SQL Server and in particular, sp_execute not being formed correctly.

    Let’s go through the steps to this point

    The developer did exactly the right steps in troubleshooting the problem. Once the application was failing due to SQL Server return errors, Profiler was enlisted to determine the exact transaction that was being sent to SQL Server. The transaction was found to be sent without specifying the parameters thought to be formed

    1. sp_executesql N'dbo.uspGetEmployeeManagers',N'@EmployeeID INT',@EmployeeID=1

    When running this, the error returned is

    Msg 201, Level 16, State 4, Procedure uspGetEmployeeManagers, Line 0
    Procedure or function 'uspGetEmployeeManagers' expects parameter '@EmployeeID', which was not supplied.

    Looking at the statement closer and verifying with BOL sp_executesql syntax, the parameter mapping is not completely set. The proper statement should be called as follows

    1. exec sp_executesql N'dbo.uspGetEmployeeManagers @EmployeeID',N'@EmployeeID INT',@EmployeeID=1

    Note the @EmployeeID added to the procedure name based.

    In order to recreate the problem entirely, the following code was used.

    1. string str = "";
    2. SqlConnection conn = new SqlConnection("Data Source=localhost;Initial Catalog=AdventureWorks;Integrated Security=SSPI;");
    3. conn.Open();
    4. SqlCommand cmd = new SqlCommand("dbo.usp_Deltest", conn);
    5. cmd.CommandType =
    6. CommandType.StoredProcedure;
    7. cmd.Parameters.Add(
    8. new SqlParameter("@EmployeeID", "1"));
    9. cmd.Parameters.Add(
    10. new SqlParameter("@ManagerID", "1"));
    11. SqlDataReader reader = cmd.ExecuteReader();
    12. while(reader.Read())
    13. {
    14. str = reader[0].ToString();
    15. }
    16. reader.Close();

    This test application appeared to work as it should and the sp_executesql was sent as expected. After exhausting attempts to force the not well-formed statement on SQL Server, sections of the .NET code itself were looked at closer. In order to test different scenarios, certain lines were commented out to change the way the code was being handled.

    Specifically, when the command type setting for stored procedure was commented out, the exact situation was successfully recreated. Unfortunately the BOL entry for SQLCommand.CommandType wasn’t much help here other than this section

    When you set the CommandType property to StoredProcedure, you should set the CommandText property to the name of the stored procedure. The command executes this stored procedure when you call one of the Execute methods.

    The Microsoft .NET Framework Data Provider for SQL Server does not support the question mark (?) placeholder for passing parameters to a SQL Statement or a stored procedure called with a CommandType of Text. In this case, named parameters must be used. For example:

    1. SELECT * FROM Customers WHERE CustomerID = @CustomerID

    Again, not a very effective section to the exact problem but it does allow us to come to the conclusion that without the CommandType being set, the parameters are essentially ignored in the procedure call from ADO.NET.

    Conclusion

    If you ever run across the error that the procedure you are calling expects a certain parameter or you see an sp_executesql statement with the same error but the SQL Server profiled transaction appears as it does from this posting, check to ensure you are setting the CommandType and using parameters correctly.

    The best lesson learned in this problem was, involving both SQL Server and .NET individuals in the steps to troubleshoot problems such as this is a great way to identify, research and resolve problems quickly. Make an effort to involve your team to make the length of time much smaller when it comes to the situations.

    About the Author

    Ted Krueger is a SQL Server MVP and has been working in development and database administration for 13+ years. Specialties range from High Availability and Disaster / Recovery setup and testing methods down to custom assembly development for SQL Server Reporting Services. Ted blogs and is also one of the founders of LessThanDot.com technology community. Some of the articles focused on are Backup / Recovery, Security, SSIS and working on SQL Server and using all of the SQL Server features available to create stable and scalable database services. @onpnt
    Social SitingsTwitterLinkedInLTD RSS Feed
    1261 views
    Instapaper

    6 comments

    Comment from: SQLDenis [Member] Email
    SQLDenis Mmmmm...where did I see this before :-)
    12/27/10 @ 10:29
    Comment from: Ted Krueger (onpnt) [Member]
    Ted Krueger (onpnt) :) Yup. That email while I was driving home was about this one. Thanks again for eyeing that parm missing in there. I didn't see it even after looking at it for what seemed, forever
    12/27/10 @ 10:30
    Comment from: SQLDenis [Member] Email
    SQLDenis Yeah that is also the reason that I don't use inline parameters like that
    12/27/10 @ 10:38
    Comment from: Naomi Nosonovsky [Member]
    Naomi Nosonovsky If the CommandType is not specified, it defaults to CommandType.Text You should always explicitly specify a commandtype if using a stored procedure.
    12/27/10 @ 11:30
    Comment from: Ted Krueger (onpnt) [Member]
    Ted Krueger (onpnt) Yup. What I was going at there...
    12/27/10 @ 11:56
    Comment from: Christiaan Baes (chrissie1) [Member]
    Christiaan Baes (chrissie1) of course you should have said to your developer that he should use conn.Createcommand and cmd.Createparameter instead. But I'm sure you did.
    12/28/10 @ 00:51

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)