将参数传递给SQL Server存储过程

时间:2018-04-11 14:35:12

标签: c# sql-server

我正在尝试将参数传递给我的应用程序中的存储过程,但我不知道我做错了什么。我收到错误

  

程序或功能' usp_getBorrowerDetails'期望参数' @ BookID',这是未提供的。

当我过世时,我做了很多事情,但仍然没有找到解决方案。

这是我的代码:

IDataReader reader = null;

SqlCommand command = new SqlCommand();

try
{
    SqlConnection connection = GetDBConnection();

    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = Constants.SP_BookBorrowerDetails;
    command = new SqlCommand(command.CommandText, connection);

    command.Parameters.AddWithValue("@BookID", bookID);

    reader = base.ExecuteReader(command);
}
catch (System.Data.SqlClient.SqlException ex)
{
    throw new Exception("Oops! Something went wrong.");
}

以下是我的存储过程:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[usp_getBorrowerDetails]
    @BookID INT
AS
    SELECT 
        Name, Mobile, ReturnDate 
    FROM
        BorrowerDetails 
    INNER JOIN
        BookDetails ON BookDetails.CurrentBorrowerID = BorrowerDetails.ID    
    WHERE
        BookDetails.BookID = @BookID
GO

如果我运行任何不需要任何参数的存储过程,它可以正常工作。只有在我添加参数时才会出现问题。

5 个答案:

答案 0 :(得分:7)

在设置commandSqlCommand后,您正在将CommandType重新定义为全新的CommandText,这意味着它将被视为纯SQL,而不是存储过程。在适当的地方创建一次。

IDataReader reader = null;
SqlCommand command;

try
{
    SqlConnection connection = GetDBConnection();

    command = new SqlCommand(Constants.SP_BookBorrowerDetails, connection);
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddWithValue("@BookID", bookID);

    reader = base.ExecuteReader(command);
}
catch (System.Data.SqlClient.SqlException ex)
{
    throw new Exception("Oops! Something went wrong.");
}

顺便说一下,您可能还应该考虑不仅保持连接打开,而是在一个方法中获取结果,而不是依靠调用代码来管理连接。

答案 1 :(得分:4)

其中一个问题是代码的顺序。您正在将命令设置为新的SqlCommand。发生这种情况时,默认的CommandType是Text。

command = new SqlCommand(command.CommandText, connection);
command.CommandType = CommandType.StoredProcedure;
command.CommandText = Constants.SP_BookBorrowerDetails;

您应首先创建命令,然后设置属性。

答案 2 :(得分:2)

此处的一种可能性是bookIDnull

Convert.ToString(null)返回:null

未附加null的参数。您需要使用DBNull.Value

但是:无论如何也没有必要让它成为string

请考虑使用:(object)bookId ?? DBNull.Value代替值,这应解决这两个问题。

编辑:如评论中所述,您还要过早地设置CommandType,然后替换命令对象;设置CommandType必须在之后 new - d变量。

注意:这些只是许多中的两个,“小巧”会帮助你;考虑:

var reader = connection.ExecuteReader(
      "usp_getBorrowerDetails", new { BookID = bookID },
      commandType: CommandType.StoredProcedure);

(虽然通常我会提倡短小精悍的Query<T>方法 - 但他们也会为你做更多的

答案 3 :(得分:0)

我相信你已经将Constants.SP_BookBorrowerDetails声明为“EXEC [dbo]。[usp_getBorrowerDetails]”,它没有预期的输入参数“@BookID”。

Command.Parameters.AddWithValue,它只接受参数名称&amp;需要传递的值。但是它仍然需要Constants.SP_BookBorrowerDetails语法中的参数,因为在执行命令文本时,“Command.Parameters”中可用的参数列表需要具有相同名称的映射参数。

using (SqlConnection connection = new SqlConnection("SQL connection string"))
        {
            connection.Open();
            try
            {
                SqlCommand command = new SqlCommand("EXEC [dbo].[usp_getBorrowerDetails] @BookID", connection);
                command.CommandType = CommandType.StoredProcedure;
                command = new SqlCommand(command.CommandText, connection);
                command.Parameters.AddWithValue("@BookID", 1);

                IDataReader reader = command.ExecuteReader();
            }
            catch (SqlException ex)
            {
                throw new Exception("Oops! Something went wrong." + ex.Message);
            }
        }

请检查上面的代码段。

如果出现任何问题,请退回。

答案 4 :(得分:0)

对我来说有用

connection = new SqlConnection(connectionString);
connection.Open();
SqlCommand  com  = new SqlCommand("usp_getBorrowerDetails", connection);
com.CommandType = CommandType.StoredProcedure;

com.Parameters.AddWithValue("@BookID", bookID);

IDataReader reader = com.ExecuteReader();

while (reader.Read())
{
   
}

reader.Close();
connection.Close();