使用 SqlDataAdapter 插入一行
Posted
技术标签:
【中文标题】使用 SqlDataAdapter 插入一行【英文标题】:Using SqlDataAdapter to insert a row 【发布时间】:2010-12-10 12:06:23 【问题描述】:我想使用 SqlDataAdapter 在数据库中插入一行。我在 CustomerOrders 数据库中有 2 个表(Custormers 和 Orders),并且有超过一千条记录。我想创建一个 GUI(文本框),用于将新客户和订单添加到数据库中各自的表中。
我该怎么做?我猜通常遵循的方法是
dataAdapter = new SqlDataAdapter (sqlQuery, conn);
dataSet = new DataSet();
da.Fill(dataSet);
现在从文本框中获取值(或使用 DataBinding)将新行添加到数据集中并调用
da.Update(dataSet);
但问题是我为什么要首先使用 da.Fill(dataSet) 将所有其他记录提取到数据集中?我只想添加一条新记录。
为此,我正在做的是在 DataSet 中创建数据库的模式。像这样:
DataSet customerOrders = new DataSet("CustomerOrders");
DataTable customers = customerOrders.Tables.Add("Customers");
DataTable orders = customerOrders.Tables.Add("Orders");
customers.Columns.Add("CustomerID", Type.GetType("System.Int32"));
customers.Columns.Add("FirstName", Type.GetType("System.String"));
customers.Columns.Add("LastName", Type.GetType("System.String"));
customers.Columns.Add("Phone", Type.GetType("System.String"));
customers.Columns.Add("Email", Type.GetType("System.String"));
orders.Columns.Add("CustomerID", Type.GetType("System.Int32"));
orders.Columns.Add("OrderID", Type.GetType("System.Int32"));
orders.Columns.Add("OrderAmount", Type.GetType("System.Double"));
orders.Columns.Add("OrderDate", Type.GetType("System.DateTime"));
customerOrders.Relations.Add("Cust_Order_Rel", customerOrders.Tables["Customers"].Columns["CustomerID"], customerOrders.Tables["Orders"].Columns["CustomerID"]);
我使用 DataBinding 将这些列绑定到相应的文本框。 现在我很困惑!接下来我该怎么办?如何使用插入命令?因为我没有给出任何 dataAdapter.SelectCommand 所以我猜 dataAdapter.Update() 不会工作。请提出正确的方法。
【问题讨论】:
【参考方案1】:使用“0 = 1”过滤器设置选择命令并使用SqlCommandBuilder,以便为您自动生成插入命令。
var sqlQuery = "select * from Customers where 0 = 1";
dataAdapter = new SqlDataAdapter(sqlQuery, conn);
dataSet = new DataSet();
dataAdapter.Fill(dataSet);
var newRow = dataSet.Tables["Customers"].NewRow();
newRow["CustomerID"] = 55;
dataSet.Tables["Customers"].Rows.Add(newRow);
new SqlCommandBuilder(dataAdapter);
dataAdapter.Update(dataSet);
【讨论】:
那个“WHERE 0 = 1”是救命稻草。 (正在将 2GB 的媒体表加载到内存中……叹息……) 我对@987654323@ 这行很感兴趣——这会产生一些神奇的效果,因此我不必编写整个 INSERT 语句的脚本。谢谢! dataSet.Tables["Customers"].Add(newRow);不编译。 “System.Data.DataTable 不包含‘添加’的定义”。你的意思是dataSet.Tables[tableName].Rows.Add(newRow);? 哪里 0=1?我认为更优雅的是 'SELECT TOP(0)...' @fcm 两个查询都应该有相同的执行计划,但是 WHERE 1 = 0 具有符合 ANSI SQL 的优点,而 TOP 关键字是特定于供应商的。任何理解任何 SQL 版本的 RDBMS 都会理解 WHERE 1 = 0。它也是代码生成的 SQL 查询中广泛使用的一种模式。【参考方案2】:您可以用空集填充dataSet
,例如:
da = new SqlDataAdapter ("SELECT * FROM Customers WHERE id = -1", conn);
dataSet = new DataSet();
da.Fill(dataSet);
然后添加行并调用更新。
对于这种情况,尽管最好不要使用SqlDataAdapter
。而是直接使用SqlCommand
对象进行插入。 (更好的是,使用 LINQ to SQL 或任何其他 ORM)
【讨论】:
我想到了。但我有一个包含 200 多个文本列的表单。所以,我选择了这个。 @Manu 如果 Id 使用负值,这将不起作用 - 您可能会返回 1 行。 Nathans 回答确保返回 0 行。但是它仍然会进行一次数据库之旅。【参考方案3】:SqlConnection con = new SqlConnection("Data Source=(local);Initial Catalog=test;Integrated Security=True");
SqlDataAdapter da=new SqlDataAdapter("Insert Into Employee values("+textBox1.Text+",'"+textBox2.Text+"','"+textBox3.Text+"',"+textBox4.Text+")",con);
DataSet ds = new DataSet();
da.Fill(ds);
我必须做第一次。你可以试试看 。效果很好。
【讨论】:
这可能有效,但至少我发现数据绑定更清晰,更不容易出现大量输入文本框的错误,并且更能抵御数据库中的表更改以上是关于使用 SqlDataAdapter 插入一行的主要内容,如果未能解决你的问题,请参考以下文章
SqlDataAdapter.Fill 运行 SQL 命令两次
.Net SqlDataAdapter 在使用列上的默认值插入后检索身份
无法在 c# 中使用 SqlDataAdapter 和 MSSqlServer 插入数据库