C# 将参数传递给SQL Server存储过程
我试图在我的应用程序中向存储过程传递一个参数,但我不知道我做错了什么。我犯了一个错误 过程或函数“usp_GetFrowerDetails”需要未提供的参数“@BookID” 当我路过的时候,我做了很多事情,但仍然没有找到解决办法 这是我的代码:C# 将参数传递给SQL Server存储过程,c#,sql-server,C#,Sql Server,我试图在我的应用程序中向存储过程传递一个参数,但我不知道我做错了什么。我犯了一个错误 过程或函数“usp_GetFrowerDetails”需要未提供的参数“@BookID” 当我路过的时候,我做了很多事情,但仍然没有找到解决办法 这是我的代码: IDataReader reader = null; SqlCommand command = new SqlCommand(); try { SqlConnection connection = GetDBConnection();
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
如果我运行任何不需要任何参数的存储过程,它就可以正常工作。只有在添加参数时才会出现问题。这里的一种可能性是
bookID
为null
Convert.ToString(null)
返回:null
未附加值为null
的参数。为此,需要使用DBNull.Value
但是:无论如何,也没有必要把它变成字符串
考虑使用:(对象)bookId??将DBNull.Value
改为值,这将解决这两个问题
编辑:如注释中所述,您还过早地设置了CommandType
,然后替换了命令对象;设置命令类型
必须在新建
-d变量后进行
注意:这些只是“整洁”能帮助你的许多事情中的两件;考虑:
var reader = connection.ExecuteReader(
"usp_getBorrowerDetails", new { BookID = bookID },
commandType: CommandType.StoredProcedure);
(虽然我通常会提倡dapper的查询方法,但它们也为您做了很多事情)这里的一种可能性是bookID
为null
Convert.ToString(null)
返回:null
未附加值为null
的参数。为此,需要使用DBNull.Value
但是:无论如何,也没有必要把它变成字符串
考虑使用:(对象)bookId??将DBNull.Value
改为值,这将解决这两个问题
编辑:如注释中所述,您还过早地设置了CommandType
,然后替换了命令对象;设置命令类型
必须在新建
-d变量后进行
注意:这些只是“整洁”能帮助你的许多事情中的两件;考虑:
var reader = connection.ExecuteReader(
"usp_getBorrowerDetails", new { BookID = bookID },
commandType: CommandType.StoredProcedure);
(虽然我通常会提倡dapper的查询方法,但它们也为您提供了更多功能)问题之一是代码的顺序。您正在将命令设置为新的SqlCommand。发生这种情况时,默认的CommandType为Text
command = new SqlCommand(command.CommandText, connection);
command.CommandType = CommandType.StoredProcedure;
command.CommandText = Constants.SP_BookBorrowerDetails;
您应该首先创建命令,然后设置属性。问题之一是代码的顺序。您正在将命令设置为新的SqlCommand。发生这种情况时,默认的CommandType为Text
command = new SqlCommand(command.CommandText, connection);
command.CommandType = CommandType.StoredProcedure;
command.CommandText = Constants.SP_BookBorrowerDetails;
您应该首先创建命令,然后设置属性。在设置了CommandType
和CommandText
之后,您将命令重新定义为全新的SqlCommand
,这意味着它将被视为纯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.");
}
顺便说一句,您可能还应该考虑不只是保持连接打开,而是在一个方法中获得结果,而不是依赖调用代码来管理连接。在设置了CommandType
和CommandText
之后,您将命令重新定义为全新的SqlCommand
,这意味着它将被视为纯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.");
}
另一方面,您可能还应该考虑不只是保持连接打开,而是在一个方法中获取结果,而不是依赖调用代码来管理连接。我相信您已经将Constants.SP_bookbrowerDetails声明为“EXEC[dbo].[usp_getbrowerDetails]”,它没有预期的输入参数“@BookID”
Command.Parameters.AddWithValue,它将只接受需要传递的参数名称和值。但它仍然需要Constants.SP_BookFrooderDetails语法中的参数,因为在执行命令文本时,“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);
}
}
请检查上面的代码片段
如果出现任何问题,请返回。我相信您已将Constants.SP_bookbrowerdetails声明为“EXEC[dbo].[usp_getbrowerdetails]”,它没有预期的输入参数“@BookID”
Command.Parameters.AddWithValue,它将只接受需要传递的参数名称和值。但它仍然需要Constants.SP_BookFrooderDetails语法中的参数,因为在执行命令文本时,“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);
}
}
请检查上面的代码片段
如果出现任何问题,请回复。这是我的工作
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();
这是我的工作
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();
不要使用常量中的AddWithValue。SP_bookbrowerDetails
?这不是答案,但您确实需要将连接包装在USING子句中。按照编码,您的连接未正确关闭和处理,这可能导致连接池被消耗。@PeterB这不是我将其更改为bookID As的情况well@SeanLangeSqlCommand对象也一样,不要使用AddWithValue,常量中的内容。SP_bookbrowerdetails
?不是答案,但确实需要包装您的连接在USING子句中。按照编码,您的连接未正确关闭和处理,这可能导致连接池被消耗。@PeterB这不是我将其更改为bookID As的情况well@SeanLange与SqlCommand对象相同,他还应该在创建新命令后设置commandtype和文本,而不是在更新代码和remo之前