如何在SQL Server中同时使用参数和函数
本文关键字:参数 函数 SQL Server | 更新日期: 2023-09-27 18:27:30
我对C#和SQL中的参数传递很陌生,但我知道实现它很关键。
场景是:
我已经在系统中内置了一个功能,但不知道如何编辑它,以便能够使用传递给它的参数。
我通过INSERT或UPDATE编辑的功能是:
namespace SQLFunc
{
class SQLClass
{
public void SQLEdit(string var_SQLCommand)
{
using (SqlConnection myConn = new SqlConnection(this.SQLConnectString))
using (SqlCommand var_command = new SqlCommand(var_SQLCommand, myConn))
{
myConn.Open();
try
{
var_command.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("An error occurred: " + ex.Message + " using SQL Query: " + var_SQLCommand, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
myConn.Close();
}
}
}
...
我使用函数的常用命令是:
using SQLFunc.SQLClass
....
//command to variable
var_Command = "UPDATE tbl_Table SET fld_Active = 'YES' WHERE fld_IDNo = " + var_A;
//execute function
var_SQLClass.SQLEdit(var_Command);
使用参数,我想去代码:
using SQLFunc.SQLClass
....
//command to variable
var_Command = "UPDATE tbl_Table SET fld_Active = 'YES' WHERE fld_IDNo = @var_A_";
// need to pass this entire line after the SQLCommand in the function SQLEdit
var_Command.Parameters.AddWithValue("var_A_", var_A );
var_SQLClass.SQLEdit(var_Command);
我希望能够在函数中使用参数传递。我可以传递变量var_A,但我希望我的代码能够满足适应性,比如它应该适用于一个字段(更新或插入)甚至10个字段(升级或插入),而不必在每次字段数量变化时更改函数的代码。
这是可以实现的吗?如果是,如何?
以下是我的操作方法。
public class SqlClass
{
public void ExecuteNonQuery(string sqlStatement, Dictionary<string, object> parameters)
{
using (SqlConnection connection = new SqlConnection(this.ConnectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = System.Data.CommandType.Text;
command.CommandText = sqlStatement;
foreach(var keyValuePair in parameters)
{
command.Parameters.Add(new SqlParameter(keyValuePair.Key, keyValuePair.Value));
}
command.ExecuteNonQuery();
}
}
}
}
您对SqlClass.ExecuteNonQuery()的调用将如下所示。
Dictionary<string, object> parameters = new Dictionary<string, object>
{
{ "@fld_Active", "Yes" },
{ "@fld_IDNo", 1 }
};
SqlClass sql = new SqlClass();
sql.ExecuteNonQuery("UPDATE tbl_Table SET fld_Active = @fld_Active WHERE fld_IDNo = @fld_IDNo",
parameters);
喜欢吗?
public void insert(string sql,Dictionary<stirng,object> parameters){
using (SqlConnection myConn = new SqlConnection(this.SQLConnectString))
using (SqlCommand var_command = new SqlCommand(var_SQLCommand, myConn))
{
myConn.Open();
try
{
foreach(string name in parameters.Keys){
var_Command.Parameters.AddWithValue(name, parameters[name] );
}
var_command.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("An error occurred: " + ex.Message + " using SQL Query: " + var_SQLCommand, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
myConn.Close();
}
}
}
如果我理解正确,你会想要一些函数SQLEdit(command, /* params */)
,这样params
就会"正常工作",并插入到查询中的正确位置。是这样吗?
如果是这样,那就很棘手了。请参阅,要使用参数化查询,必须提供SqlParameter
对象。反过来,他们需要知道参数的SQL Server数据类型,而这是无法自动推断的。例如,DateTime
可能是Time、DateTime或DateTime2之一。字符串可以是char、nchar、varchar、nvarchar、text、ntext。。。你明白了。
最好的(如果最详细的话)选择是让params
像params SqlParameter parameters
一样,并在使用它们的地方自己构建单独的参数。尝试构建自己的映射算法会让你付出高昂的代价。
如果您想要易用性,可以使用各种ORM中的任何一种(实体框架、Dapper等)。如果您想要原始SQL的性能,请准备编写一些代码。
为了让事情变得不那么冗长,您可以编写一个助手函数来为您创建参数对象,类似于以下内容,我在内存中完成了这项操作,但尚未进行测试:
public static SqlParameter Create(string name, SqlDbType type, object value)
{
var p = new SqlParameter();
p.ParameterName = name;
p.SqlDbType = type;
// If type is a fixed-length type, maybe set the correct string length here
if (value == null)
{
p.SqlValue = DBNull.Value;
}
else
{
p.SqlValue = value;
}
return p;
}