怎样将新建的DataTable写入数据库?

本文介绍了一种将DataTable中的数据批量插入到SQL Server数据库的方法。通过创建参数化的SQL命令,该方法能够有效地将每一条记录插入到指定的表中,并返回成功插入的记录数。此过程使用了ADO.NET中的SqlConnection和SqlCommand对象。

原文出处:

http://www.programfan.com/club/showpost.asp?id=20894

 

/// <summary>
///把数据集DataTable中数据插入数据库,返回int
/// </summary>
/// <param name="SQLString"></param>
/// <returns></returns>
public   static   int   InsertTable(DataTable   table)   
{   

int   ret   =0; 


string   strInsert   =   "INSERT   INTO   serverInfo(收购商名称,服务器类型,服务器名称,玩家类型,价格,数量,信息采集地址,收购状态,信息采集时间) values (@收购商名称,@服务器类型,@服务器名称,@玩家类型,@价格,@数量,@信息采集地址,@收购状态,@信息采集时间)";   
    
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand   com   =   new   SqlCommand(strInsert,conn);   
  
    
SqlParameter   p1   =   new   SqlParameter("@收购商名称",SqlDbType.VarChar,10);   
SqlParameter   p2   =   new   SqlParameter("@服务器类型",SqlDbType.VarChar,4);   
SqlParameter   p4   =   new   SqlParameter("@服务器名称",SqlDbType.VarChar,50);   
SqlParameter   p3   =   new   SqlParameter("@玩家类型",SqlDbType.VarChar,50);   
SqlParameter   p5   =   new   SqlParameter("@价格",SqlDbType.Float,8);   
SqlParameter   p6   =   new   SqlParameter("@数量",SqlDbType.VarChar,10);   
SqlParameter   p7   =   new   SqlParameter("@信息采集地址",SqlDbType.VarChar,50);   
SqlParameter   p8   =   new   SqlParameter("@收购状态",SqlDbType.VarChar,10);   
SqlParameter   p9   =   new   SqlParameter("@信息采集时间",SqlDbType.DateTime,8);

    
com.Parameters.Add(p1);   
com.Parameters.Add(p2);   
com.Parameters.Add(p3);   
com.Parameters.Add(p4);   
com.Parameters.Add(p5);   
com.Parameters.Add(p6);   
com.Parameters.Add(p7);   
com.Parameters.Add(p8);   
com.Parameters.Add(p9);

com.CommandType = CommandType.Text;

conn.Open(); 
try
{
  
for(int   i=0;i<table.Rows.Count;i++)   
{   
DataRow   row   =   table.Rows[i];   
  
p1.Value   =   row["收购商名称"].ToString();   
p2.Value   =   row["服务器类型"].ToString();   
p3.Value   =   row["服务器名称"].ToString();   
p4.Value   =   row["玩家类型"].ToString();   
p5.Value   =   row["价格"].ToString();   
p6.Value   =   row["数量"].ToString();   
p7.Value   =   row["信息采集地址"].ToString();   
p8.Value   =   row["收购状态"].ToString();   
p9.Value   =   row["信息采集时间"].ToString();      
ret   +=   com.ExecuteNonQuery();   

com.Dispose();
conn.Close(); 
return   ret;
}
catch(System.Data.SqlClient.SqlException err)
{
     MessageBox.Show(err.ToString());
return 0;
}
}

<think>嗯,用户这次的问题是如何用C#实现DataGridView和SQLite数据库的双向数据交互。结合之前提供的三个引用,虽然都不是直接针对SQLite的,但其中提到了数据库连接和Excel操作的技术点,可以借鉴部分思路。用户显然是个C#开发者,正在处理桌面应用的数据持久化需求。从提问方式看,ta已经有一定C#基础,知道DataGridView组件,但对SQLite的具体操作不熟悉。真正需要的不是零散的代码片段,而是一个完整的可运行解决方案——特别是SQLite这种轻量级数据库在本地应用中的典型用法。注意到引用[2]提到了SQLCipher库,这说明用户可能接触过加密数据库的需求,虽然当前问题没明确要求加密,但后续可能会涉及。准备在回答里提前埋个拓展说明会比较周到。技术上需要解决几个关键点:1.SQLite连接字符串的写法(和之前的Access连接不同)2.DataGridView与DataTable的绑定机制3.SQLite的参数化查询(防注入很重要)4.事务处理(导入时批量操作需要)示例代码要突出实用性:导出时考虑整表导出和条件导出两种场景;导入则要处理数据冲突的常见情况。特别要注意的是,SQLite不需要像Access那样单独安装驱动,直接用System.Data.SQLite包就行。用户可能没意识到但实际会遇到的两个坑:-SQLite的日期格式处理-空值在DataGridView中的转换这些在注释里都得重点标注。最后预留的拓展方向是有意的:因为这种基础功能完善后,用户接下来必然会问性能优化或加密,提前准备接续点能减少后续沟通成本。</think> 好的,这里提供一个完整的C#示例,展示如何将`DataGridView`(简称`DGV`)的数据**导出**到SQLite数据库以及从SQLite数据库**导入**到`DataGridView`中。 **核心思路:** 1. **连接SQLite数据库:** 使用合适的ADO.NET Provider (`System.Data.SQLite`库)。 2. **导出 (DGV -> SQLite):** * 遍历`DGV`的每一行。 * 为每一行构造一个参数化的SQL `INSERT`语句。 * 执行`INSERT`语句,将数据写入SQLite数据库表。 3. **导入 (SQLite -> DGV):** * 使用SQL `SELECT`语句从SQLite数据库表中查询数据。 * 将查询结果填充到`DataTable`。 * 将`DataTable`绑定到`DataGridView`的数据源。 **步骤与代码示例:** 1. **添加必要的引用 (NuGet Package):** 在Visual Studio中,通过NuGet包管理器安装 `System.Data.SQLite` 包。这是访问SQLite数据库的核心库。 ``` Install-Package System.Data.SQLite ``` 2. **准备Form:** * 在Form上放置一个`DataGridView`控件 (`dataGridView1`)。 * 放置两个按钮:`btnExport`(导出到SQLite)、`btnImport`(从SQLite导入)。 * (可选)放置一个`TextBox`或`SaveFileDialog`让用户选择或输入数据库文件路径。 3. **定义SQLite连接字符串 (替换路径):** 需要根据你的实际路径修改`dbFilePath`。 ```csharp // 假设数据库文件名为 'mydatabase.db',放在应用程序启动目录下的 'Data' 文件夹中 (可自行修改) string dbFilePath = Path.Combine(Application.StartupPath, @"Data\mydatabase.db"); string connectionString = $"Data Source={dbFilePath};Version=3;"; ``` 4. **导出到SQLite代码 (`btnExport` Click 事件):** ```csharp private void btnExport_Click(object sender, EventArgs e) { try { // 创建连接 using (SQLiteConnection connection = new SQLiteConnection(connectionString)) { connection.Open(); // 开始一个事务,提高批量插入性能 using (SQLiteTransaction transaction = connection.BeginTransaction()) { // 假设目标表叫 'MyDataTable' (根据你的实际表名修改) string sqlInsert = "INSERT INTO MyDataTable (Column1, Column2, ...) VALUES (@value1, @value2, ...);"; // 循环遍历DGV每一行 foreach (DataGridViewRow dgvRow in dataGridView1.Rows) { // 检查是否是新建行(最后一行) if (!dgvRow.IsNewRow) { using (SQLiteCommand command = new SQLiteCommand(sqlInsert, connection, transaction)) { // 为参数赋值 // 假设你的表有两列: 'Name'(nvarchar) 和 'Age'(integer) // 修改@参数名、列名和赋值逻辑以匹配你的表结构和DGV列! command.Parameters.AddWithValue("@value1", dgvRow.Cells["ColumnNameName"].Value?.ToString() ?? DBNull.Value); // 处理null command.Parameters.AddWithValue("@value2", Convert.ToInt32(dgvRow.Cells["ColumnNameAge"].Value ?? 0)); // 处理null和类型转换 //... 继续为表中其他列添加参数 ... // 执行INSERT command.ExecuteNonQuery(); } } } // 提交事务 transaction.Commit(); } } MessageBox.Show("数据成功导出到SQLite数据库!"); } catch (Exception ex) { MessageBox.Show("导出失败: " + ex.Message); } } ``` **关键点说明:** * **表名 (`MyDataTable`) 和 列名 (`Column1`, `Column2`等):** **必须**替换为你的SQLite数据库中实际的表名和列名。 * **参数赋值 (`@value1`, `@value2`):** SQL语句中的参数名 (`@value1`, `@value2`) 必须与 `command.Parameters.AddWithValue` 中使用的参数名**完全一致**。参数值来源于对应的`DataGridView`单元格 (`dgvRow.Cells["YourColumnName"].Value`)。 * **Null 值处理:** 使用 `?.` 安全访问和 `?? DBNull.Value` 将C# `null` 转换为数据库能理解的 `DBNull`。 * **数据类型转换:** 确保DGV单元格值的类型能够转换为目标SQLite列的类型。`Convert.ToInt32`, `Convert.ToDouble` 等在此处做转换。 * **`IsNewRow`: 排除空行。** * **事务 (`Transaction`):** 在循环外部开始事务,循环内部插入数据,最后提交事务,极大地提升了批量数据插入的效率。 5. **从SQLite导入数据代码 (`btnImport` Click 事件):** ```csharp private void btnImport_Click(object sender, EventArgs e) { try { DataTable dt = new DataTable(); // 创建连接和命令 using (SQLiteConnection connection = new SQLiteConnection(connectionString)) { connection.Open(); // 查询数据 (替换表名和列名为你的实际情况) string sqlSelect = "SELECT Column1, Column2, ... FROM MyDataTable;"; using (SQLiteCommand command = new SQLiteCommand(sqlSelect, connection)) { // 使用DataAdapter填充DataTable using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(command)) { adapter.Fill(dt); } } } // 将DataTable绑定到DataGridView dataGridView1.DataSource = dt; MessageBox.Show("数据成功从SQLite数据库导入!"); } catch (Exception ex) { MessageBox.Show("导入失败: " + ex.Message); } } ``` **关键点说明:** * **SQL语句 (`sqlSelect`):** 这是查询数据的SQL语句,`SELECT * FROM MyDataTable` 会获取所有列的所有数据。你可以根据需求修改,例如添加 `WHERE` 条件过滤。**替换 `MyDataTable` 为你的表名**。 * **`SQLiteDataAdapter`: 负责执行SQL命令并用结果填充 `DataTable`(`dt`)**。 * **`dataGridView1.DataSource = dt`:** 这是将查询到的数据(`dt`)显示在`DataGridView`上的核心绑定语句。`DGV`会自动根据`DataTable`的结构创建列并填充数据。 **重要提示:** 1. **列映射 (最关键):** 确保`DataGridView`的列名 (你在导出时 `dgvRow.Cells["YourColumnName"]` 中用的名字) 与你代码中**实际使用的 `DataGridView` 列的 `Name` 属性一致**!通常在窗体设计器中设置列的`Name`属性或者通过代码添加列时设置。同样,`INSERT`语句中的列名 (`Column1`, `Column2`) 必须和SQLite数据库表的实际列名一致。`SELECT`语句也要正确映射回来。 2. **数据库文件路径:** 确保代码中 `dbFilePath` 指定的路径存在且应用程序有读写权限。 3. **表结构:** 在运行导出代码之前,请确保SQLite数据库中已经存在名为 `MyDataTable`(或你修改后的名字)的表,并且表的列定义(列名、数据类型)能够兼容你要从`DGV`导出的数据。如果表不存在,你需要先执行`CREATE TABLE`语句创建它。这可以在安装程序/第一次运行时完成,也可以用代码在执行`INSERT`前检查表是否存在并创建。 4. **错误处理:** 示例中提供了基本错误处理(`try...catch`),生产环境可能需要更详细的错误日志记录。 5. **性能:** 对于大量数据,示例中的导出方式(逐行插入)在事务包裹下性能尚可。对于极其大量的数据 (>10万行),可能需要考虑批量插入优化策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值