获取c#方法中存储过程的返回值
本文关键字:返回值 存储过程 方法 获取 | 更新日期: 2023-09-27 17:53:18
我正在使用visual studio 2010创建一个带有数据库的c# web应用程序。我的目标是违约。Aspx调用一个c#类,该类运行一个存储过程,从表中选择一个条目并返回它。下面是代码:
'The stored procedure. I want it to send back the name it gets from doing
'the query to the c# class.
ALTER PROCEDURE getName (@id int)
AS
BEGIN
SET NOCOUNT ON;
--
SELECT name FROM tableA where id = @id;
END
Return
//Here's the c# class I'm using.
public class student
{
public string name;
public int id;
public student()
{ }
public String doQuery(int id)
{
SqlConnection conn = null;
try
{
conn = new SqlConnection("Server =(local); Database = Database1.mdf;
Integrated Security = SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand("getName", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter("@id", SqlDbType.Int);
param.Direction = ParameterDirection.Input;
param.Value = id;
cmd.Parameters.Add(param);
//This is some code from when I tryed return value
//SqlParameter reVal = cmd.Parameters.Add("@name", SqlDbType.VarChar);
//reVal.Direction = ParameterDirection.ReturnValue;
//before using ExecuteScalar I tried ExcuteNonQuery with the commented
//out code
name = (string)cmd.ExecuteScalar();
//name = (String)cmd.Parameters["@name"].Value;
conn.Close();
}
catch(Exception)
{}
return name;
}
}
运行我的程序不会返回错误,它只是没有在name中放置任何值。我错过了什么是在sql过程中选择到我的c#类的名称变量的名称。我希望我清楚地表达了我的问题。
edit1:我没有在catch中添加任何内容,因为我还没有决定使用什么来查看它是否出错。我将其更改为使name = "error"当它失败时,这就是我得到的,这就是我得到的。我还尝试在sql server管理中运行"exec getName 5,其他东西"。我有点不清楚在运行exec getName时使用什么作为第二个参数,因为第二个参数应该只是输出,但似乎仍然需要运行它。它只显示命令执行成功但不显示id 5
我建议对SQL语句使用async
/await
模式。幸运的是,它不需要太多的重构。
看看是否适合你:
public async Task<string> QueryGetNameAsync(int id)
{
using (var dbConn = new SqlConnection("..."))
using (var command = new SqlCommand("getName", dbConn))
{
try
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@id", id);
await dbConn.OpenAsync();
var result = await command.ExecuteScalarAsync();
dbConn.Close();
var name = result as string;
return name;
}
catch (Exception ex)
{
// Handle exception here.
}
}
}
你可以这样调用它:
private async void DoLookup_Clicked(object sender, EventArgs e)
{
var id = int.Parse(idText.Text);
var name = await QueryGetNameAsync(id);
}
或者,可以在SQL中使用OUTPUT
参数,但您必须将存储过程调整为如下内容:
ALTER PROCEDURE getName
(
@id int,
@name varchar(100) OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
SELECT @name = name FROM tableA where id = @id;
END
那么你的 c# 函数应该是这样的:
public async Task<string> QueryGetNameAsync(int id)
{
using (var dbConn = new SqlConnection("..."))
using (var command = new SqlCommand("getName", dbConn))
{
try
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@id", id);
command.Parameters.Add("@name", SqlDbType.VarChar, 100);
command.Parameters["@name"].Direction = ParameterDirection.Output;
await dbConn.OpenAsync();
await command.ExecuteNonQueryAsync();
dbConn.Close();
var name = command.Parameters["@name"].Value as string;
return name;
}
catch (Exception ex)
{
// Handle exception here.
}
}
}
问题在于您的连接字符串:除非您有奇怪的命名约定,否则您指定的是数据库文件名,而不是数据库本身的名称。
尝试更改连接字符串的这一部分:Database = Database1.mdf;
到Database = Database1;
。
如果您对连接字符串中有效或无效的内容感到困惑,您可以始终使用SqlConnectionStringBuilder,它将在您设置正确的属性后为您创建适当的连接字符串。
还可以使用SqlConnection中指定的属性列表。作为包含示例的参考的ConnectionString文档。
最后,我强烈推荐以下最佳实践:
1)使用using块连接和命令,以确保它们被正确关闭和处置。
2)不要将name直接赋值给ExecuteScalar的结果,以免返回DBNull。值
3)永远不要忽略异常,除非你在代码中记录了为什么要这样做。
下面是一个快速重写的所有上述建议:
try
{
using (var conn = new SqlConnection("Server =(local); Database = Database1; Integrated Security = SSPI"))
{
conn.Open();
using (var cmd = new SqlCommand("getName", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
var param = new SqlParameter("@id", SqlDbType.Int);
param.Direction = ParameterDirection.Input;
param.Value = id;
cmd.Parameters.Add(param);
var oResult = cmd.ExecuteScalar();
if ((oResult != null) && (oResult != DBNull.Value))
{
name = (string)oResult;
}
}
conn.Close();
}
}
catch (Exception)
{
// Do something with the exception here, don't just ignore it
}