tags:

views:

168

answers:

4

I have a stored procedure that has a parameter called UserName and in my code behind I have a SqlCommand object that I add the parameters to with the Add method. But for some reason when the command object tries to run the ExecuteReader method, it throws an exception. I am totally at a loss and have no idea why it's not recognizing the parameter. Before the ExecuteReader method is run I have a break point set so I can confirm the command object does contain the parameters being set, which is true. I know the stored procedure does return the correct data when the parameters are not added to the command object, but are hard coded in the actual stored procedure. Below is the exception message that is given in the catch block. I will also paste my code and first part of stored procedure. I would greatly appreciate any help in this issue, seeing that I have tried many different approaches to no avail. Thanks in advance.



Exception Message

Procedure or function 'someStoredProcedure' expects parameter '@UserName', which was not supplied.



Code Behind

private DataTable GetLossMitData(string code, DateTime? start, DateTime? end)  
{  
DataTable results = new DataTable();  
string connectionString = ConfigurationManager.ConnectionStrings["asdf"].ConnectionString;  
string userName = String.Empty;  

try  
{  
    using (SPSite site = new SPSite(ConfigurationManager.AppSettings["someName"]))  
    {  
        using (SPWeb web = site.OpenWeb())  
        {  
            userName = web.CurrentUser.Email.ToString();  
        }  
    }  

    using (SqlConnection connection1 = new SqlConnection(connectionString))  
    {  
         connection1.Open();  
         using (SqlCommand command1 = new SqlCommand("someStoredProcedure", connection1))  
         {  
             command1.Parameters.Add(new SqlParameter("@UserName", userName));  
             command1.Parameters.Add(new SqlParameter("@ProductCode", code));  

             SqlDataReader dr = command1.ExecuteReader(CommandBehavior.CloseConnection);  
             results.Load(dr);  
         }  
         connection1.Close();  
    }  
}  
catch (Exception ex)  
{  
}  
return results;  
}  



Stored Procedure

@UserName nvarchar(256),  
@ProductCode nvarchar(256),
@StartDate nvarchar(256) = '1/1/1900',
@EndDate nvarchar(256) = '12/30/2012'

AS
BEGIN
SET NOCOUNT ON;

Declare @UserID int

Select @UserID = Users.UserID
from Users
where Users.Email = @UserName
+3  A: 

By default, the CommandText property needs to contain a complete SQL command, not just the name of the stored procedure.

You can change this by to set the SqlCommand's CommandType property to StoredProcedure.

Alternatively, you could explicitly pass the parameters, by changing the CommandText to "someStoredProcedure @UserName, @ProductCode"; this is a complete SQL statement and will work with the default CommandType of Text.

EDIT: I just tried it, and the only way to get that error message without setting CommandType to StoredProcedure (which he did not do) is if CommandText is EXEC someStoredProcedure. Passing a null parameter gives a different error.

SLaks
You get an "Incorrect syntax near..." error if it's not set to StoredProcedure, so I don't think it's this. I've reproduced the error as given by OP, using @Ray's answer so I think he may be correct
AdaTheDev
+1 as I've reproduced also it this way now. It appears it matters what version of SQL Server you're using - SQL 2008 reports this as the error given by the OP. In SQL 2000 (and I think 2005 though I need to recheck), it's reported as I said in my comment above - "Incorrect syntax...". Think I may knock up a blog post on this!
AdaTheDev
+3  A: 

Try making sure that the command type is set to stored procedure.

mycommand.CommandType = System.Data.CommandType.StoredProcedure;
Aaron
You get an "Incorrect syntax near..." error if it's not set to StoredProcedure, so I don't think it's this
AdaTheDev
@Ray's answer doesn't make sense given the context. If the command type is set to Text, then calling this stored procedure will never work unless you do something like @SLaks suggested by placing the parameters within the statement. Changing the command type to stored procedure should most definitely work.
Aaron
If anything, getting an error whenever the command type is not set to stored procedure only seems to provide more evidence that this is in fact the issue.
Aaron
The error message returned by sql server indicates that it knows that the command is a stored proc call. I agree with you that it should be explicitly setup in the command object so sql server doesn't have to guess, but I don't think this causes the error.
Ray
@Aaron - Thanks for your answer. This fixed my issue.
jhorton
@Ray - The reason that this does cause the issue is because you're sending SQL a text command like "exec SPROC". If SPROC is supposed to accept parameters and you do not specify those parameters within the text command, then the command type must be changed to stored procedure so that it can be sent to the SQL server correctly. That is why OP got an "expects parameter" error.
Aaron
@Aaron - I see what you mean, but it causes a different error for me. When I remove the commandType for an otherwise functioning command, I get a sql syntax error (I can see it while watching the profiler). I wonder how, in the original question, sql server knew that a stored proc was being called.
Ray
+1 as I've also reproduced it giving the same error. There are it seems multiple ways to get this error, and interestingly it matters what version of SQL Server you are using!
AdaTheDev
+1  A: 

You will get this exception if the value of your 'userName' variable is null

If null is valid, then pass 'DBNull.Value' to the db instead:

command1.Parameters.Add(new SqlParameter("@UserName", (userName ?? DBNull.Value));   
Ray
+1 - this is what I was thinking
AdaTheDev
Wrong. That's not the problem here, and it wouldn't throw this exception anyway.
SLaks
@SLaks - Your downvote is a bit hasty - I make this mistake all too frequently, and this is the exception that I get to spank me
Ray
Actually, I didn't downvote; somebody else did. However, you're still wrong.
SLaks
userName is not null and should never be null as long as they have logged in. But I say should as if anything in code is ever certain. But I will add that just in case. Thanks
jhorton
@Slaks - Sorry for the assumption. @jhorton - "should never be null" - I have said that myself once or twice, which is why I have seen this same exception happen to me.
Ray
@jhorton - it sounds like you do not want to use my DBNull.Value suggestion if you have a null userName - if you are always supposed to have a value, then you will probably want to test for null elsewhere and throw your own exception.
Ray
I have to still agree with @Ray. I was sure I've had this myself in the past, so I've just knocked up a test to make sure - when I set a parameter in this way using null as the value, it **does** end up throwing this exact error. So, still +1 from me!
AdaTheDev
I just tried it. You **are** wrong on both counts.
SLaks
I just tried it and got the exception. @SLaks - do you have a default value for the parameter in your stored proc? If so, you won't get this error.
Ray
Just because it works with default values does not mean that this is logically the right choice. I believe that if you define default values it will in fact work; however, the default values will be used instead of any passed ones unless you change the command type to stored procedure.
Aaron
No, I don't. What exactly did you try?
SLaks
@Ray - I will be using the DBNull suggestion, so I do appreciate the suggestion. But the actual fix is declaring the command type. So the DBNull actually fixes my second issue. So I will mark this as an answer as well. Thanks again.
jhorton
@Slaks - I modified a working command parameter like this, just to force the issue: command.Parameters.AddWithValue("@parameter_name", null); When I ran the command I got the exception. When I returned the parameter to its original state (with a proper value) the exception went away.
Ray
+1  A: 
Command1.CommandType = System.Data.CommandType.StoredProcedure

This will force the ExecuteReader to perform the exec instead of just trying it as a flat command.

Craig