如何使用 C# 将二维数组插入数据库

How to insert a 2D Array into Database using c#

我有一个two dimensional array with 3 columns and 2 rows。我也有一个database table with 3 columns。我想直接将二维数组插入数据库。

有什么办法吗?

感谢任何帮助。如果需要,我可以提供更多详细信息。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace _2DArrayIntoDatabaseTest
{

public partial class Form1 : Form
{

 string[,] LoginInfo = new string[2, 3]{{"1", "Admin", "123"},{"2", "Admin2", "456"}};
 string query;
 SqlCommand Sqlcmd;
 SqlConnection conn = new SqlConnection(@"Data Source=MIRAZ-PC\SQLEXPRESS;
                      Initial Catalog=2DArrayIntoDatabaseTest;
                      Integrated Security=True");
 DataTable dbdataset;

 public Form1()
 {
  InitializeComponent();
 }

 private void Form1_Load(object sender, EventArgs e)
 {
  this.tTableAdapter.Fill(this._2DArrayIntoDatabaseTestDataSet.t);
 }

 int i = 0, j = 0;

 private void button1_Click(object sender, EventArgs e)
 {

  try
  {

   for (i = 0; i < 2; i++)
   {

    for (j = 0; j < 3;j++ )
     query = "INSERT INTO t(SerialNumber,UserName,Password) 
             values( '" + LoginInfo[i, 0] + "','" 
                        + LoginInfo[i, 1] + "','" 
                        + LoginInfo[i, 2] + "')";
   }

   Sqlcmd = new SqlCommand(query, conn);
   conn.Open();
   Sqlcmd.ExecuteNonQuery();
   conn.Close();

  }
  catch(Exception ex)
  {
   MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
  }

  try
  {

   query = "SELECT * from t";
   Sqlcmd = new SqlCommand(query, conn);
   conn.Open();
   SqlDataAdapter sda = new SqlDataAdapter();
   sda.SelectCommand = Sqlcmd;
   dbdataset = new DataTable();
   sda.Fill(dbdataset);
   BindingSource bSource = new BindingSource();
   bSource.DataSource = dbdataset;
   dataGridView1.DataSource = bSource;
   sda.Update(dbdataset);
   //dataGridView1.Columns.Remove("rownum");

  }
  catch (Exception ex)
  {
   MessageBox.Show(ex.Message);
  }
  finally
  {
   conn.Close();
  }
}
}
}

现在这段代码可以正常编译了。但是在数据网格视图中我只能看到 1 行而不是 2 行。

如何解决?

注意:这里我尝试使用嵌套循环创建一个动态查询来一次插入一行数据。

您需要 [i, 0][i, 1][i, 2],而不是 [i, 1][i, 2][i, 3]。此外,ExecuteNonQuery() 需要发生在 内部 for 循环中。

当我在这里时,我还将展示一些关于在 SQL 查询中包含数据的更好的做法。当前代码极易受到 sql 注入的攻击。

private void button1_Click(object sender, EventArgs e)
{
    string query = "INSERT INTO t(SerialNumber,UserName,Password) VALUES (@serial, @user, @pass);";
    var dbdataset = new DataTable();

    //ADO.Net does better if you create new objects, rather than try to re-use them through a class or application.
    // The "using" blocks will make sure things are closed and disposed properly, even if an exception is thrown
    using (var conn = new SqlConnection(@"Data Source=MIRAZ-PC\SQLEXPRESS;Initial Catalog=2DArrayIntoDatabaseTest;Integrated Security=True"))
    using (var cmd = new SqlCommand(query, conn))
    {   
        //I had to guess at column types and lengths here.
        // You should use actual column types and lengths from the DB
        cmd.Parameters.Add("@serial", SqlDbType.NVarChar, 20);
        cmd.Parameters.Add("@user", SqlDbType.NVarChar, 20);  
        cmd.Parameters.Add("@pass", SqlDbType.NVarChar, 20);
        conn.Open();

        for (i = 0; i < LoginInfo.GetUpperBound(0); i++)
        {
            cmd.Parameters["@serial"].Value = LoginInfo[i, 0];
            cmd.Parameters["@user"].Value = LoginInfo[i, 1];
            cmd.Parameters["@pass"].Value = LoginInfo[i, 2];

            try
            {
                //don't forget to do this INSIDE the loop
                cmd.ExecuteNonQuery();
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        cmd.CommandText = "SELECT * FROM t";
        var sda = new SqlDataAdapter(cmd);

        try
        {
            sda.Fill(dbdataset);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    dataGridView1.DataSource = dbdataset;
}

最后...像这样的纯文本密码不好。


这是一个使用 List<UserLoginInfo> 的示例。请注意,将代码移动到新的 DB class 并不是列表工作所必需的;无论如何,这样做是个好习惯。

public class UserLoginInfo
{
    public string SerialNumber {get;set;} //you might want an int here instead
    public string Username {get;set;}
    public string Password {get;set;}
}

public static class DB
{
    private static readonly string ConnectionString = @"Data Source=MIRAZ-PC\SQLEXPRESS;Initial Catalog=2DArrayIntoDatabaseTest;Integrated Security=True";

    public static void SaveUserData(IEnumerable<UserLoginInfo> users)
    {
        string query = "INSERT INTO t(SerialNumber,UserName,Password) VALUES (@serial, @user, @pass);";

        using (var conn = new SqlConnection(ConnectionString))
        using (var cmd = new SqlCommand(query, conn))
        {   
            cmd.Parameters.Add("@serial", SqlDbType.NVarChar, 20);
            cmd.Parameters.Add("@user", SqlDbType.NVarChar, 20);  
            cmd.Parameters.Add("@pass", SqlDbType.NVarChar, 20);
            conn.Open();

            foreach(var user in users)
            {
                cmd.Parameters["@serial"].Value = user.SerialNumber;
                cmd.Parameters["@user"].Value = user.UserName;
                cmd.Parameters["@pass"].Value = user.Password;
                cmd.ExecuteNonQuery();
            }
        }
    }

    public static DataTable GetLoginData()
    {
        var result = new DataTable();
        using (var conn = new SqlConnection(ConnectionString))
        using (var cmd = new SqlCommand("SELECT * FROM t", conn))
        using (var sda = new SqlDataAdapter(cmd))
        {
            sda.Fill(result);
        }
        return result;
    }
}

public partial class Form1 : Form
{
    private List<UserLoginInfo> LoginInfo = new List<UserLoginInfo> {
        new UserLoginInfo() {SerialNumber = "1", Username = "Admin", Password = "123"}, 
        new UserLoginInfo() {SerialNumber = "2", UserName = "Admin2", Password = "456"}
    };

    private void button1_Click(object sender, EventArgs e)
    {
        try 
        {
            DB.SaveUserData(LoginInfo);
            dataGridView1.DataSource = DB.GetLoginData();
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }    
    }
}

是的,这很容易做到。我在 vb.net 中完成了此操作,如下所示。我采用了具有 4 列和两行的数组 arr..

            Dim Arr()() = {({1, "Document Title", "TITLE", "C"}),
                          ({2, "Company Header1", "HEADER1", "C"})}

现在要将其插入数据库,您只需 运行 插入查询以您自己的方式插入数据...例如

    for each item in arr.items
         exexuteNonQuery("INSERT INTO Supplier (SupplierID, Name, abc,xyz) VALUES (@SID, @Name, @abc, @xyz)")
    next