简体   繁体   English

使用相同的参数化查询添加多个SQL值?

[英]Add multiple SQL values with same parameterized query?

I'm fairly new to SQL and trying to figure out the best way to add some predefined data. 我对SQL还是很陌生,并试图找出添加一些预定义数据的最佳方法。 I figured out from searching around here that I should used a parameterized command to avoid a sql injection attack which isn't a huge concern in this case but I would like to avoid the possibility and learn to do it right... Anyway here is the code I have right now: 我从这里搜索发现,我应该使用参数化的命令来避免sql注入攻击,在这种情况下这不是什么大问题,但是我想避免这种可能性,并学习正确地做...无论如何,这里我现在拥有的代码:

        using (SqlTransaction trans = connection.BeginTransaction())
        {
            foreach (IEnumerable<string> row in table.RowData)
            {
                using (SqlCommand sql = new SqlCommand("INSERT INTO " + table.Title
                    + " (" + string.Join(", ", table.Headers)
                    + ") VALUES (" + string.Join(", ", table.Headers.Select(x => "@" + x)) + ");", connection, trans))
                {

                    for (int i = 0; i < table.Headers.Count(); i++)
                    {
                        if (string.IsNullOrEmpty(row.ElementAt(i)))
                        { sql.Parameters.AddWithValue("@" + table.Headers.ElementAt(i), DBNull.Value); }
                        else
                        { sql.Parameters.AddWithValue("@" + table.Headers.ElementAt(i), row.ElementAt(i)); }
                    }
                    sql.ExecuteNonQuery();
                }
            }
            trans.Commit();
        }

This seems to work and all the data gets in there but it 'feels' inefficient to me. 这似乎可行,所有数据都存储在其中,但对我来说“感觉”效率低下。 I'm wrapping it in a transaction so there is only one commit, but it's creating the parameters every time and just setting different values for each row. 我将其包装在一个事务中,因此只有一次提交,但是它每次都会创建参数,并且仅为每一行设置不同的值。

Is there a way to make this use the same parameters but just set different values per row? 有没有一种方法可以使它使用相同的参数,但只为每行设置不同的值? Or is this the best way to do this and I should not worry about it? 还是这是执行此操作的最佳方法,我不应该担心吗?

Thanks in advance for any help you can give. 在此先感谢您提供的任何帮助。

We can do what you want by parsing the headers into parameters in a pre-processing step. 我们可以通过在预处理步骤中将标头解析为参数来完成您想要的操作。 I have also removed the explicit transaction because every single insert already gets an implicit transaction by default (why pay the performance penalty of two transactions?). 我还删除了显式事务,因为默认情况下每个插入都已经获得了一个隐式事务(为什么要为两个事务付出性能损失?)。

using (var command = new SqlCommand()) {
    command.CommandText =
        "INSERT INTO " + table.Title + " ("
      + string.Join(", ", table.Headers)
      + ") VALUES ("
      + string.Join(", ", table.Headers.Select(x => "@" + x))
      + ");";
    command.Connection = connection;

    foreach (var header in table.Headers) {
        /*
             Add all parameters as strings. One could choose to infer the
             data types by inspecting the first N rows or by using some sort
             of specification to map the types from A to B.
         */
        command.Parameters.Add("@" + header, typeof(string));
    }

    foreach (var row in table.RowData) {
        for (var i = 0; i < table.Headers.Count(); i++) {
            if (!string.IsNullOrEmpty(row.ElementAt(i))) {
                command.Parameters["@" + table.Headers.ElementAt(i)].Value = row.ElementAt(i);
            }
            else {
                command.Parameters["@" + table.Headers.ElementAt(i)].Value = DBNull.Value;
            }
        }

        command.ExecuteNonQuery();
    }
}

Yes, you can be much more effecient by reusing SqlParameter objects. 是的,通过重用SqlParameter对象可以提高效率。 Here is some pseudo code: 这是一些伪代码:

        const string sql = "INSERT INTO table1 (column1) VALUES (@p0)";
        using (var sqlCommand = new SqlCommand(sql, connection, transaction))
        {
            var param1 = sqlCommand.Parameters.Add("@p0", SqlDbType.Int);
            foreach (var row in table)
            {
                param1.Value = row["value"];
                sqlCommand.ExecuteNonQuery();
            }
        }

this is my example of insert that works for me 这是适合我的插入示例

  private void insertWordCount(string songId, string wordId, int wordCount)
    {
        string query = "insert into songs_words_conn values(@wordId,@songId,@wordCount)";
        SqlCommand cmd = new SqlCommand(query, conn);

        cmd.Parameters.AddWithValue("@wordId", wordId);
        cmd.Parameters.AddWithValue("@songId", songId);
        cmd.Parameters.AddWithValue("@wordCount", wordCount);

        cmd.ExecuteNonQuery();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM