从 class 调用方法时参数化数据输入
Parameterize data input when calling methods from a class
我正在尝试通过 WPF Window 插入一些数据,我想对输入进行参数化。我怎样才能做到这一点?到目前为止我的代码:
public int insertdetails(string query)
{
SqlTransaction trans = null;
try
{
trans = getconnection().BeginTransaction("trInsert");
SqlCommand cmd = new SqlCommand("", con, trans);
cmd.CommandText = query;
int a = cmd.ExecuteNonQuery();
if (a > 0)
{
trans.Commit();
return 1;
}
else
{
trans.Rollback("trInsert");
return 0;
}
//....below is the code for button save....//
dataaccess da = new dataaccess(); //..this is a class with insert method..//
res = da.insertdetails("insert into staff_table values ('" + txtid.text + "','"+ txtname.text + "','" + txtlname.text + "'");
if(res > 0)
messagebox.show("saved!");
else
messagebox.show("error!");
你是说 String.Format 吗?
da.insertdetails(String.Format("insert into staff_table values ('{0}','{1}','{2}')",txtid.text,txtname.text,txtlname.text));
在 C#6 中,您可以使用 String Interpolation 功能将 $
放在字符串的开头。
da.insertdetails($"insert into staff_table values ('{txtid.text}','{txtname.text}','{txtlname.text}')");
您需要更换 insertdetails 方法来接受参数和命令。使用 SqlParameter class 是避免 SQL-Injections:
的方法
用法:
insertdetails("insert into staff_table", "A", "B", "C");
或
insertdetails("insert into staff_table (col1, col2)", "A", "B");
代码:
public int insertdetails(string command, params string[] parameters)
{
SqlTransaction trans = null;
try
{
trans = getconnection().BeginTransaction("trInsert");
SqlCommand sqlCom = new SqlCommand()
{
Connection = con,
Transaction = trans
};
// Start Building the Parameterized Command
string insertedValues = String.Empty;
if (parameters.Any())
{
int counter = 1;
foreach (var paramVal in parameters)
{
string paramName = "@param" + counter++;
sqlCom.Parameters.AddWithValue(paramName, paramVal);
insertedValues += paramName + ",";
}
insertedValues = insertedValues.TrimEnd(',');
insertedValues = String.Format(" VALUES ( {0} )", insertedValues);
}
sqlCom.CommandText = String.Format("{0} {1}", command, insertedValues);
int resCount = sqlCom.ExecuteNonQuery();
if (resCount > 0)
{
trans.Commit();
return 1;
}
else
{
trans.Rollback("trInsert");
return 0;
}
}
catch (Exception ex)
{
// Exception Handling
if (trans != null)
trans.Rollback();
return 0;
}
}
使用 SqlParameter to parametrize the SqlCommand query 的可能解决方案如下所示:
首先为重复代码创建一个通用方法,以创建 SqlParameter 对象(在您的情况下,看起来所有参数都是 string/varchar 类型):
public SqlParameter createParameter(string name, string value)
{
// create the named parameter
var sqlParameter = new SqlParameter(name, SqlDbType.VarChar);
// set the desired value
sqlParameter.Value = value;
return sqlParameter;
}
然后将sql命令写成普通查询,参数名作为占位符,在执行前将参数添加到SqlCommand对象中:
dataaccess da = new dataaccess();
var sqlQuery = new SqlCommand("insert into staff_table values ('@id','@name','@lname')");
sqlQuery.Parameters.Add(createParameter("id", txtid.text));
sqlQuery.Parameters.Add(createParameter("name", txtname.text));
sqlQuery.Parameters.Add(createParameter("lname", txtlname.text));
res = da.insertdetails(sqlQuery);
if(res > 0)
messagebox.show("saved!");
else
messagebox.show("error!");
@
符号标记 sql 查询中的参数。 ADO.NET 框架在参数列表中搜索名称并用转义值替换任何匹配项。您的代码对 sql 注入尝试是安全的。
您可能必须稍微更改 insertdetails
方法,以便仅将查询和参数或 SqlCommand 作为参数,而不仅仅是 sql 查询。
你有很多选择。一种是将 query
参数更改为 SqlCommand
:
public int insertdetails(SqlCommand cmd)
{
SqlTransaction trans = null;
try
{
trans = getconnection().BeginTransaction("trInsert");
cmd.Transaction = trans;
int a = cmd.ExecuteNonQuery();
if (a > 0)
{
trans.Commit();
return 1;
}
else
{
trans.Rollback("trInsert");
return 0;
}
现在你可以使用我的答案中的其他代码了。另一种可能性是像 @user3185569 的答案一样更改您的代码。两种变体各有利弊。
我正在尝试通过 WPF Window 插入一些数据,我想对输入进行参数化。我怎样才能做到这一点?到目前为止我的代码:
public int insertdetails(string query)
{
SqlTransaction trans = null;
try
{
trans = getconnection().BeginTransaction("trInsert");
SqlCommand cmd = new SqlCommand("", con, trans);
cmd.CommandText = query;
int a = cmd.ExecuteNonQuery();
if (a > 0)
{
trans.Commit();
return 1;
}
else
{
trans.Rollback("trInsert");
return 0;
}
//....below is the code for button save....//
dataaccess da = new dataaccess(); //..this is a class with insert method..//
res = da.insertdetails("insert into staff_table values ('" + txtid.text + "','"+ txtname.text + "','" + txtlname.text + "'");
if(res > 0)
messagebox.show("saved!");
else
messagebox.show("error!");
你是说 String.Format 吗?
da.insertdetails(String.Format("insert into staff_table values ('{0}','{1}','{2}')",txtid.text,txtname.text,txtlname.text));
在 C#6 中,您可以使用 String Interpolation 功能将 $
放在字符串的开头。
da.insertdetails($"insert into staff_table values ('{txtid.text}','{txtname.text}','{txtlname.text}')");
您需要更换 insertdetails 方法来接受参数和命令。使用 SqlParameter class 是避免 SQL-Injections:
的方法用法:
insertdetails("insert into staff_table", "A", "B", "C");
或
insertdetails("insert into staff_table (col1, col2)", "A", "B");
代码:
public int insertdetails(string command, params string[] parameters)
{
SqlTransaction trans = null;
try
{
trans = getconnection().BeginTransaction("trInsert");
SqlCommand sqlCom = new SqlCommand()
{
Connection = con,
Transaction = trans
};
// Start Building the Parameterized Command
string insertedValues = String.Empty;
if (parameters.Any())
{
int counter = 1;
foreach (var paramVal in parameters)
{
string paramName = "@param" + counter++;
sqlCom.Parameters.AddWithValue(paramName, paramVal);
insertedValues += paramName + ",";
}
insertedValues = insertedValues.TrimEnd(',');
insertedValues = String.Format(" VALUES ( {0} )", insertedValues);
}
sqlCom.CommandText = String.Format("{0} {1}", command, insertedValues);
int resCount = sqlCom.ExecuteNonQuery();
if (resCount > 0)
{
trans.Commit();
return 1;
}
else
{
trans.Rollback("trInsert");
return 0;
}
}
catch (Exception ex)
{
// Exception Handling
if (trans != null)
trans.Rollback();
return 0;
}
}
使用 SqlParameter to parametrize the SqlCommand query 的可能解决方案如下所示:
首先为重复代码创建一个通用方法,以创建 SqlParameter 对象(在您的情况下,看起来所有参数都是 string/varchar 类型):
public SqlParameter createParameter(string name, string value)
{
// create the named parameter
var sqlParameter = new SqlParameter(name, SqlDbType.VarChar);
// set the desired value
sqlParameter.Value = value;
return sqlParameter;
}
然后将sql命令写成普通查询,参数名作为占位符,在执行前将参数添加到SqlCommand对象中:
dataaccess da = new dataaccess();
var sqlQuery = new SqlCommand("insert into staff_table values ('@id','@name','@lname')");
sqlQuery.Parameters.Add(createParameter("id", txtid.text));
sqlQuery.Parameters.Add(createParameter("name", txtname.text));
sqlQuery.Parameters.Add(createParameter("lname", txtlname.text));
res = da.insertdetails(sqlQuery);
if(res > 0)
messagebox.show("saved!");
else
messagebox.show("error!");
@
符号标记 sql 查询中的参数。 ADO.NET 框架在参数列表中搜索名称并用转义值替换任何匹配项。您的代码对 sql 注入尝试是安全的。
您可能必须稍微更改 insertdetails
方法,以便仅将查询和参数或 SqlCommand 作为参数,而不仅仅是 sql 查询。
你有很多选择。一种是将 query
参数更改为 SqlCommand
:
public int insertdetails(SqlCommand cmd)
{
SqlTransaction trans = null;
try
{
trans = getconnection().BeginTransaction("trInsert");
cmd.Transaction = trans;
int a = cmd.ExecuteNonQuery();
if (a > 0)
{
trans.Commit();
return 1;
}
else
{
trans.Rollback("trInsert");
return 0;
}
现在你可以使用我的答案中的其他代码了。另一种可能性是像 @user3185569 的答案一样更改您的代码。两种变体各有利弊。