【问题标题】:SQL Query says a parameter is not supplied, but is added to the SqlCommand objectSQL Query 表示未提供参数,但已添加到 SqlCommand 对象
【发布时间】:2010-02-17 15:55:58
【问题描述】:

我有一个存储过程,它有一个名为 UserName 的参数,在我后面的代码中,我有一个 SqlCommand 对象,我使用 Add 方法将参数添加到该对象中。但是由于某种原因,当命令对象尝试运行 ExecuteReader 方法时,它会引发异常。我完全不知所措,不知道为什么它不能识别参数。在运行 ExecuteReader 方法之前,我设置了一个断点,因此我可以确认命令对象确实包含正在设置的参数,这是真的。我知道当参数未添加到命令对象时,存储过程确实返回了正确的数据,但在实际存储过程中被硬编码。以下是 catch 块中给出的异常消息。我还将粘贴我的代码和存储过程的第一部分。看到我尝试了许多不同的方法都无济于事,我将不胜感激。提前致谢。



异常信息

过程或函数“someStoredProcedure”需要参数“@UserName”,但未提供该参数。



代码隐藏

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;  
}  



存储过程

@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

【问题讨论】:

标签: c# .net sql ado.net


【解决方案1】:

尝试确保命令类型设置为存储过程。

mycommand.CommandType = System.Data.CommandType.StoredProcedure;

【讨论】:

  • 如果没有设置为 StoredProcedure,你会得到一个“Incorrect syntax near...”错误,所以我不认为是这个
  • @Ray 的回答在上下文中没有意义。如果命令类型设置为文本,那么调用此存储过程将永远不会起作用,除非您通过在语句中放置参数来执行 @SLaks 建议的操作。将命令类型更改为存储过程应该绝对有效。
  • 如果有的话,只要命令类型未设置为存储过程就会出错,这似乎只是提供更多证据证明这实际上是问题所在。
  • sql server 返回的错误信息表明它知道该命令是一个存储的proc调用。我同意你的观点,它应该在命令对象中显式设置,这样 sql server 就不必猜测了,但我认为这不会导致错误。
  • @Aaron - 感谢您的回答。这解决了我的问题。
【解决方案2】:

如果您的 'userName' 变量的值为 null,您将收到此异常

如果 null 有效,则将 'DBNull.Value' 传递给数据库:

command1.Parameters.Add(new SqlParameter("@UserName", (userName ?? DBNull.Value));   

【讨论】:

  • 错了。这不是这里的问题,它也不会抛出这个异常。
  • @SLaks - 你的投票有点仓促 - 我经常犯这个错误,这是我打我的例外
  • 其实我没有投反对票;别人做了。但是,你还是错了。
  • userName 不为空,只要他们登录就永远不应该为空。但我说应该好像代码中的任何东西都是确定的。但我会补充一点以防万一。谢谢
  • @Slaks - 抱歉假设。 @jhorton - “永远不应该为空” - 我曾经说过自己一两次,这就是为什么我看到同样的异常发生在我身上的原因。
【解决方案3】:
Command1.CommandType = System.Data.CommandType.StoredProcedure

这将强制 ExecuteReader 执行 exec 而不是仅仅将其作为平面命令尝试。

【讨论】:

    【解决方案4】:

    默认情况下,CommandText 属性需要包含完整的 SQL 命令,而不仅仅是存储过程的名称。

    您可以通过将SqlCommandCommandType 属性设置为StoredProcedure 来更改此设置。

    或者,您可以通过将CommandText 更改为"someStoredProcedure @UserName, @ProductCode" 来显式传递参数;这是一个完整的 SQL 语句,可以使用默认的 CommandTypeText

    编辑:我刚刚尝试过,而在不将CommandType 设置为StoredProcedure(他没有这样做)的情况下获取该错误消息的唯一方法是如果CommandText 是@987654333 @。传递 null 参数会产生不同的错误。

    【讨论】:

    • 如果未设置为 StoredProcedure,您会收到“附近语法不正确”错误,所以我认为不是这样。我已经使用@Ray 的答案重现了 OP 给出的错误,所以我认为他可能是正确的
    • +1 因为我现在也以这种方式复制了它。您使用的 SQL Server 版本似乎很重要 - SQL 2008 将此报告为 OP 给出的错误。在 SQL 2000(我认为 2005 虽然我需要重新检查)中,正如我在上面的评论中所说的那样报告了它 - “语法不正确......”。我想我可能会写一篇关于这个的博客文章!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 2011-07-26
    • 2021-09-08
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    相关资源
    最近更新 更多