C# 以Datatable的形式从存储过程获取数据
我有一种方法可以使用存储过程作为DataTable从数据库检索数据,如:C# 以Datatable的形式从存储过程获取数据,c#,sql-server,winforms,C#,Sql Server,Winforms,我有一种方法可以使用存储过程作为DataTable从数据库检索数据,如: public DataTable GetTableBySQL(string sql) { SqlCommand cmd = new SqlCommand(sql.ToString(), this.dbconn) { CommandTimeout = 0, CommandType = CommandType.Text }; DataTable tbl =
public DataTable GetTableBySQL(string sql)
{
SqlCommand cmd = new SqlCommand(sql.ToString(), this.dbconn)
{
CommandTimeout = 0,
CommandType = CommandType.Text
};
DataTable tbl = new DataTable("Table1")
{
Locale = System.Globalization.CultureInfo.InvariantCulture
};
SqlDataAdapter da = new SqlDataAdapter(cmd);
try
{
da.SelectCommand.CommandTimeout = 0;
da.Fill(tbl);
}
catch (SqlException e)
{
this.HandleSQLError(e, "GetTableBySQL", sql.ToString());
}
finally
{
cmd.Dispose();
da.Dispose();
}
return tbl;
}
现在我这样调用存储过程:
var empList = db.GetTableBySQL("$exec getMySP");
public DataTable GetTableBySQL(string sql, params SqlParameter[] parameters)
{
var result = new DataTable();
//ADO.Net really does work better when you create a **NEW** connection
// object for most queries. Just share the connection string.
//Also: "using" blocks are a better way to make sure the connection is closed.
using (var dbconn = new SqlConnection(this.dbConnectionString))
using (var cmd = new SqlCommand(sql, dbconn))
using (var da = new SqlDataAdapter(cmd))
{
cmd.CommandTimeout = 0;
// A number of the properties set on the cmd and tbl variables just set the same value that was already there, didn't accomplish anything
//It's hard to understate how important it is to use parameterized queries.
if (parameters != null && parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
try
{
da.Fill(result);
}
catch (SqlException e)
{
this.HandleSQLError(e, "GetTableBySQL", sql.ToString());
//you may want to re-throw here,
// or even just remove the try/catch and let the error bubble up to calling code
}
}
return result;
}
var empList = db.GetTableBySQL("exec getMySP");
但当我执行时,它不会返回任何列
我做错了什么?关于这里有三个主要问题,其他较小的问题,但有三个是重要的: SQL的$exec部分没有任何意义。也许你只是想要执行官。 当坏SQL失败时,程序会隐藏错误,因此您不知道发生了什么。 方法签名不支持查询参数,因此将迫使您编写极不安全的代码,这将导致有人入侵您的应用程序。可能早一点,而不是晚一点。这真的很糟糕,你不应该忽视它。 尝试类似以下内容:
var empList = db.GetTableBySQL("$exec getMySP");
public DataTable GetTableBySQL(string sql, params SqlParameter[] parameters)
{
var result = new DataTable();
//ADO.Net really does work better when you create a **NEW** connection
// object for most queries. Just share the connection string.
//Also: "using" blocks are a better way to make sure the connection is closed.
using (var dbconn = new SqlConnection(this.dbConnectionString))
using (var cmd = new SqlCommand(sql, dbconn))
using (var da = new SqlDataAdapter(cmd))
{
cmd.CommandTimeout = 0;
// A number of the properties set on the cmd and tbl variables just set the same value that was already there, didn't accomplish anything
//It's hard to understate how important it is to use parameterized queries.
if (parameters != null && parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
try
{
da.Fill(result);
}
catch (SqlException e)
{
this.HandleSQLError(e, "GetTableBySQL", sql.ToString());
//you may want to re-throw here,
// or even just remove the try/catch and let the error bubble up to calling code
}
}
return result;
}
var empList = db.GetTableBySQL("exec getMySP");
这里同样没有所有额外的解释性注释,因此您可以看到正确操作代码更少,而不是更多:
public DataTable GetTableBySQL(string sql, params SqlParameter[] parameters)
{
var result = new DataTable();
using (var dbconn = new SqlConnection(this.dbConnectionString))
using (var cmd = new SqlCommand(sql, dbconn))
using (var da = new SqlDataAdapter(cmd))
{
cmd.CommandTimeout = 0;
if (parameters != null && parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
da.Fill(result);
}
return result;
}
那么就这样称呼它:
var empList = db.GetTableBySQL("$exec getMySP");
public DataTable GetTableBySQL(string sql, params SqlParameter[] parameters)
{
var result = new DataTable();
//ADO.Net really does work better when you create a **NEW** connection
// object for most queries. Just share the connection string.
//Also: "using" blocks are a better way to make sure the connection is closed.
using (var dbconn = new SqlConnection(this.dbConnectionString))
using (var cmd = new SqlCommand(sql, dbconn))
using (var da = new SqlDataAdapter(cmd))
{
cmd.CommandTimeout = 0;
// A number of the properties set on the cmd and tbl variables just set the same value that was already there, didn't accomplish anything
//It's hard to understate how important it is to use parameterized queries.
if (parameters != null && parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
try
{
da.Fill(result);
}
catch (SqlException e)
{
this.HandleSQLError(e, "GetTableBySQL", sql.ToString());
//you may want to re-throw here,
// or even just remove the try/catch and let the error bubble up to calling code
}
}
return result;
}
var empList = db.GetTableBySQL("exec getMySP");
在c语言中,我们使用$进行插值,所以你们可以使用string.Format,我发现了这个问题。调用SP的正确方法是db.GetTableBySQL$exec getMySP;,你的答案也是正确的。谢谢,但是这个字符串中没有插值大括号,所以你要求语言做额外的工作,寻找不会改变任何东西的大括号。只需从这个字符串中删除$,并且只在需要时使用它。对。非常感谢。