2

我真的不知道如何在标题中很好地解释它,但这是我的问题。

在许多重载方法中,我制作了这种方法,其唯一目的是将给定值插入给定表中:

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;
        }
    }
}

现在它没有使用参数化查询,不是吗?

我真的很想在其中实现这个概念,但我不知道如何。

4

3 回答 3

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"};
于 2012-12-25T22:15:23.223 回答
1

如果您在插入语句中使用位置值,则在添加、删除或重新排序表列时会遇到问题。使用命名插入是一个更好的主意

INSERT INTO mytable (col1, col2, col3) VALUES (x, y, z)

因此,您还必须传递列名。这还允许您跳过非必需列或标识列和时间戳、计算列或由触发器填充的列。

public static int Insert(string cs, string table, string[] columns, object[] values)

我还将值数组的类型更改为,object[]因为这允许您以正确的类型传递值(例如,整数值 asint或日期/时间值 as DateTime。此外,我们不会将值直接添加到 sql 语句中,相反,我们使用参数占位符 ( @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]);
}

其他部分(打开连接、创建和执行命令等)保持不变。


例子:

int result = Insert(
    cs, "mytable", 
    new string[] { "id", "name", "birthdate" },
    new object[] { 107, "John", new DateTime(1980,7,19) }
);
于 2012-12-25T22:24:56.657 回答
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]);
        }

}
于 2012-12-25T22:26:07.380 回答