如何将 ExecuteScalar 与存储过程一起使用?
How do I use ExecuteScalar with a stored Procedure?
我正在尝试获取 Sql 数据库中列记录的计数并将结果显示在 MessageBox 中。
这是我的代码:
public DataTable CheckIfNameExist(string name)
{
con = Connect();
cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "spCheckIfNameExist";
cmd.Parameters.AddWithValue("@Name", SqlDbType.NVarChar).Value = name;
MessageBox.Show(name);
Int32 totalNames = (Int32) cmd.ExecuteScalar();
string tNames = totalNames.ToString();
MessageBox.Show(tNames);
}
这是我的sp:
@Name nvarchar(50) = null
As
Begin
SELECT COUNT(*) from OrdersSent where CustomerName LIKE @Name + '%'
End
问题:
总是returns0.
您需要像这样指定命令的类型:
cmd.CommandText = "spCheckIfNameExist";
cmd.CommandType = CommandType.StoredProcedure;
另请参阅:
What is the benefit of using CommandType.StoredProcedure versus using CommandType.Text?
虽然直接指定类型并使用 Value
属性 比 AddWithValue
更好:
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
以下文章也可能很有趣:
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
你的 C# 代码有一些问题 - 最重要的可能是这个:
cmd.Parameters.AddWithValue("@Name", SqlDbType.NVarChar).Value = name;
Don't use AddWithValue
. 使用 Add
。
此外,您没有指定命令类型 - 默认为 Text
。
而且您正在使用 SqlConnection
和 SqlCommand
的字段 - 这也是错误的做法。您应该在使用它们的每个方法中创建和处理它们。
您的代码的更好版本是:
using(var con = new SqlConnection(ConnectionString))
{
using(var cmd = new SqlCommand("spCheckIfNameExist", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
con.Open();
var tNames = cmd.ExecuteScalar().ToString();
}
}
另一件让我困惑的事情是为什么一个名为 CheckIfNameExist
return 的方法是 DataTable
。我希望它只是 return a bool
.
如果你真的只想检查名称是否存在,你可以在 SQL 级别和 c# 级别上做得更好。
更好的SQL应该是这样的:
SELECT CAST(CASE WHEN EXISTS(
SELECT 1
FROM OrdersSent
WHERE CustomerName LIKE @Name + '%'
) THEN 1 ELSE 0 END AS bit)
而在 c# 级别,位直接转换为 bool,因此代码可以简单为:
public bool CheckIfNameExist(string name)
{
using(var con = new SqlConnection(ConnectionString))
{
using(var cmd = new SqlCommand("spCheckIfNameExist", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
con.Open();
return (bool)cmd.ExecuteScalar();
}
}
}
还有一条注意事项 - 您应该避免对存储过程使用 sp
前缀。
Microsoft 已为内置系统过程保留此前缀。
有关详细信息,请阅读 Aaron Bertrand 的 Is the sp_ prefix still a no-no?,您会在其中看到此问题的简短答案是 "Yes"。
The sp_ prefix does not mean what you think it does: most people think sp stands for "stored procedure" when in fact it means "special." Stored procedures (as well as tables and views) stored in master with an sp_ prefix are accessible from any database without a proper reference (assuming a local version does not exist). If the procedure is marked as a system object (using sp_MS_marksystemobject (an undocumented and unsupported system procedure that sets is_ms_shipped to 1), then the procedure in master will execute in the context of the calling database.
您的代码中有几个错误:
你应该写成:
cmd.CommandText = "spCheckIfNameExist";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
首先你需要告诉ADO引擎你正在调用一个存储过程而不是一个简单的命令文本,但是你还需要使用Add而不是AddWithValue来准确地确定传递给SP的参数类型.您的代码创建一个参数 int 因为 AddWithValue 的第二个参数是参数的值而不是类型。
我正在尝试获取 Sql 数据库中列记录的计数并将结果显示在 MessageBox 中。
这是我的代码:
public DataTable CheckIfNameExist(string name)
{
con = Connect();
cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "spCheckIfNameExist";
cmd.Parameters.AddWithValue("@Name", SqlDbType.NVarChar).Value = name;
MessageBox.Show(name);
Int32 totalNames = (Int32) cmd.ExecuteScalar();
string tNames = totalNames.ToString();
MessageBox.Show(tNames);
}
这是我的sp:
@Name nvarchar(50) = null
As
Begin
SELECT COUNT(*) from OrdersSent where CustomerName LIKE @Name + '%'
End
问题:
总是returns0.
您需要像这样指定命令的类型:
cmd.CommandText = "spCheckIfNameExist";
cmd.CommandType = CommandType.StoredProcedure;
另请参阅:
What is the benefit of using CommandType.StoredProcedure versus using CommandType.Text?
虽然直接指定类型并使用 Value
属性 比 AddWithValue
更好:
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
以下文章也可能很有趣:
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
你的 C# 代码有一些问题 - 最重要的可能是这个:
cmd.Parameters.AddWithValue("@Name", SqlDbType.NVarChar).Value = name;
Don't use AddWithValue
. 使用 Add
。
此外,您没有指定命令类型 - 默认为 Text
。
而且您正在使用 SqlConnection
和 SqlCommand
的字段 - 这也是错误的做法。您应该在使用它们的每个方法中创建和处理它们。
您的代码的更好版本是:
using(var con = new SqlConnection(ConnectionString))
{
using(var cmd = new SqlCommand("spCheckIfNameExist", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
con.Open();
var tNames = cmd.ExecuteScalar().ToString();
}
}
另一件让我困惑的事情是为什么一个名为 CheckIfNameExist
return 的方法是 DataTable
。我希望它只是 return a bool
.
如果你真的只想检查名称是否存在,你可以在 SQL 级别和 c# 级别上做得更好。
更好的SQL应该是这样的:
SELECT CAST(CASE WHEN EXISTS(
SELECT 1
FROM OrdersSent
WHERE CustomerName LIKE @Name + '%'
) THEN 1 ELSE 0 END AS bit)
而在 c# 级别,位直接转换为 bool,因此代码可以简单为:
public bool CheckIfNameExist(string name)
{
using(var con = new SqlConnection(ConnectionString))
{
using(var cmd = new SqlCommand("spCheckIfNameExist", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
con.Open();
return (bool)cmd.ExecuteScalar();
}
}
}
还有一条注意事项 - 您应该避免对存储过程使用 sp
前缀。
Microsoft 已为内置系统过程保留此前缀。
有关详细信息,请阅读 Aaron Bertrand 的 Is the sp_ prefix still a no-no?,您会在其中看到此问题的简短答案是 "Yes"。
The sp_ prefix does not mean what you think it does: most people think sp stands for "stored procedure" when in fact it means "special." Stored procedures (as well as tables and views) stored in master with an sp_ prefix are accessible from any database without a proper reference (assuming a local version does not exist). If the procedure is marked as a system object (using sp_MS_marksystemobject (an undocumented and unsupported system procedure that sets is_ms_shipped to 1), then the procedure in master will execute in the context of the calling database.
您的代码中有几个错误: 你应该写成:
cmd.CommandText = "spCheckIfNameExist";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name;
首先你需要告诉ADO引擎你正在调用一个存储过程而不是一个简单的命令文本,但是你还需要使用Add而不是AddWithValue来准确地确定传递给SP的参数类型.您的代码创建一个参数 int 因为 AddWithValue 的第二个参数是参数的值而不是类型。