我正在尝试将参数传递给我的应用程序中的存储过程,但我不知道我做错了什么。我收到错误
当我过世时,我做了很多事情,但仍然没有找到解决方案。程序或功能' 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
如果我运行任何不需要任何参数的存储过程,它可以正常工作。只有在我添加参数时才会出现问题。
答案 0 :(得分:7)
在设置command
和SqlCommand
后,您正在将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)
此处的一种可能性是bookID
为null
。
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();