我真的不知道如何在标题中解释清楚,但这是我的问题。
在我使用这种方法的许多重载方法中,唯一的目的是将给定值插入到给定表中:
public static int Insert(string cs, string table, string[] values)
{
using (SqlConnection con = new SqlConnection(cs))
{
try
{
string strCommand = string.Format(
"INSERT INTO {0} VALUES ({1})",
table,
values.Aggregate((a, b) => (a + ", " +b)));
SqlCommand com = new SqlCommand(strCommand, con);
con.Open();
int result = com.ExecuteNonQuery();
return result;
}
catch (SqlException ex)
{
HttpContext.Current.Response.Write(ex.Message);
return 0;
}
}
}
现在它不使用参数化查询,不是吗?
我真的想在其中实现这个概念,但我不知道如何。
答案 0 :(得分:1)
您需要更改方法以传递带有参数名称的字符串数组和包含参数值的等长对象数组
public static int Insert(string cs, string table, string[] paramNames, object[] paramValues)
{
using (SqlConnection con = new SqlConnection(cs))
{
try
{
string strCommand = string.Format(
"INSERT INTO {0} VALUES ({1})", table,
paramNames.Aggregate((a, b) => (a + ", " +b)));
SqlCommand com = new SqlCommand(strCommand, con);
for(int x = 0; x < paramNames.Length; x++)
com.Parameters.AddWithValue(paramNames[x], paramValues[x]);
con.Open();
int result = com.ExecuteNonQuery();
return result;
}
catch (SqlException ex)
{
HttpContext.Current.Response.Write(ex.Message);
return 0;
}
}
}
你可以使用类似的东西来调用这个程序
string[] parNames = new string[] {"@keyID", "@custName"};
object[] parValues = new object[] {1, "Mike"};
DBHelper.Insert("constring", "customers", parNames, parValues);
然而,让我说,这种方法有很多弊端。因为您没有传递一组特定的列,所以您必须为每个列传递值,如果您的表包含Identity列,这将给您带来问题。 (您无法明确为Identity列设置值。)
因此,传递一组列名而不是一组参数名要好得多 使用此数组,您可以更好地自定义查询(例如省略字段),参数名称可以通过列名称派生。
public static int Insert(string cs, string table, string[] colNames, object[] paramValues)
{
......
string strCommand = string.Format(
"INSERT INTO {0} ({1}) VALUES ({2})", table,
colNames.Aggregate((a, b) => (a + ", " +b)),
colNames.Select(n => "@" + n).Aggregate((a, b) => (a + ", " + b)));
.....
for(int x = 0; x < colNamesNames.Length; x++)
com.Parameters.AddWithValue("@" + colNames[x], paramValues[x]);
}
当然在调用中更改参数以使用列名而不是参数名。
string[] colNames = new string[] {"ID", "Name"};
答案 1 :(得分:1)
如果在insert语句中使用位置值,则在添加,删除或重新排序表列时会遇到问题。使用命名插入
是一个更好的主意INSERT INTO mytable (col1, col2, col3) VALUES (x, y, z)
因此您也必须传递列名。这也允许您跳过不需要的列或标识列以及由触发器填充的时间戳,计算列或列。
public static int Insert(string cs, string table, string[] columns, object[] values)
我还将values数组的类型更改为object[]
,因为这允许您以正确的类型传递值(例如,整数值为int
或日期/时间值为{{} 1}}。
此外,我们不会将值直接添加到sql语句,而是使用参数占位符(DateTime
)。这里我们只使用前缀为“@”的列名。
@xy
INSERT INTO mytable (col1, col2, col3) VALUES (@col1, @col2, @col3)
现在我们必须将值作为参数添加到string cmd = string.Format(
"INSERT INTO {0} ({1}) VALUES ({2})",
table,
columns.Aggregate((a, b) => (a + ", " + b))
columns.Select(c => "@" + c).Aggregate((a, b) => (a + ", " + b)));
SqlCommand
其他部分(打开连接,创建和执行命令等)保持不变。
示例:
for (int i = 0; i < columns.Length; i++) {
com.AddWithValue("@" + columns[i], values[i]);
}
答案 2 :(得分:1)
您可以使用包含列名称及其各自值的字典
Dictionary<string, object> values = new Dictionary<string,object>();
values.Add("userid", 1022);
values.Add("username", "JFord");
values.Add("IsActive", 0);
string table = "users";
用法:
MyClass.Insert("connection", "users", values);
方法
public static int Insert(string cs, string table, Dictionary<string,object> values)
{
string strCommand = string.Format("INSERT INTO {0} VALUES ({1})",
table, "@"+String.Join(", @", values.Keys));
//strCommand becomes: "INSERT INTO users VALUES (@userid, @username, @IsActive)"
SqlCommand com = new SqlCommand(strCommand, conn);
foreach (string key in values.Keys)
{
com.Parameters.AddWithValue("@" + key, values[key]);
}
}