Asp.net 使用ms access db通过一个查询插入多行
我试图将多行放入一个表中,因此我试图获取行号并将其放入for循环中,Asp.net 使用ms access db通过一个查询插入多行,asp.net,vb.net,ms-access,oledb,insert-select,Asp.net,Vb.net,Ms Access,Oledb,Insert Select,我试图将多行放入一个表中,因此我试图获取行号并将其放入for循环中,countC与select语句的行数完全相同,因此不存在问题 我使用oledb连接,因为我的代码在vb asp.net中,但我的数据库在ms access 2003中 For c As Integer = 1 To countC Dim cmdstring As String cmdstring = " INSERT INTO [KN - ProductionMachineAllocation]
countC
与select语句的行数完全相同,因此不存在问题
我使用oledb连接,因为我的代码在vb asp.net中,但我的数据库在ms access 2003中
For c As Integer = 1 To countC
Dim cmdstring As String
cmdstring = " INSERT INTO [KN - ProductionMachineAllocation] (BatchNo, ComponentID)
SELECT POH.BatchNo, SSCDD.ComponentID
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY BatchNo ASC) AS rownumber
([KN - ProductionOrderHeader] AS POH
INNER JOIN [FG - End Product Codes] AS EPC
ON POH.ProductID = EPC.ProductID)
INNER JOIN ([KN - ProductionOrderDetails] AS POD
INNER JOIN [FG - Style Size Comp Def Details] AS SSCDD
ON POD.SizeID = SSCDD.SizeID)
ON (POH.BatchNo = POD.BatchNo)
AND (EPC.StyleID = SSCDD.StyleID)
WHERE POH.BatchNo = '" & BatchNo & "'
) AS temptablename
WHERE rownumber IN (" & c & ");"
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Shantara Production IT.mdb")
Dim cmd As New OleDbCommand(cmdstring)
cmd.CommandType = CommandType.Text
cmd.Connection = con
cmd.Connection.Open()
cmd.ExecuteNonQuery()
cmd.Connection.Close()
Next
我发现ms access不支持
ROW_NUMBER()
,所以我需要在每行中找到另一个,因为ms access不支持select语句(如我的语句)中的多行按insert-by-insert-into,对我的问题有什么建议吗?好的,所以我终于找到了解决方法,这是一个有点长的过程,但基本上我将SELECT语句(包含多行)加载到gridview表中,并使用for循环将其插入到insert into语句中。下面是我的代码:
在桌子上展示
Dim Adapter As New OleDbDataAdapter
Dim Data As New DataTable
Dim SQL As String
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Shantara Production IT.mdb")
Dim cmd As New OleDbCommand()
grdvmachincomp.Visible = false
SQL = "SELECT DISTINCT POH.BatchNo, SSCDD.ComponentID
FROM ([KN - ProductionOrderHeader] AS POH
INNER Join [FG - End Product Codes] AS EPC
On POH.ProductID = EPC.ProductID)
INNER Join([KN - ProductionOrderDetails] AS POD
INNER Join [FG - Style Size Comp Def Details] AS SSCDD
On POD.SizeID = SSCDD.SizeID)
On (POH.BatchNo = POD.BatchNo)
And (EPC.StyleID = SSCDD.StyleID)
WHERE POH.BatchNo = '" & BatchNo & "'"
con.Open()
cmd.Connection = con
cmd.CommandText = SQL
Adapter.SelectCommand = cmd
Adapter.Fill(Data)
grdvmachincomp.DataSource = Data
grdvmachincomp.DataBind()
cmd.Connection.Close()
插入到直通for循环中
For c As Integer = 0 To grdvmachincomp.Rows.Count - 1
Dim cmdstring As String
cmdstring = " INSERT INTO [KN - ProductionMachineAllocation] (BatchNo, ComponentID) VALUES('" & grdvmachincomp.Rows(c).Cells(0).Text & "', " & grdvmachincomp.Rows(c).Cells(1).Text & ");"
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Shantara Production IT.mdb")
Dim cmd As New OleDbCommand(cmdstring)
cmd.CommandType = CommandType.Text
cmd.Connection = con
cmd.Connection.Open()
cmd.ExecuteNonQuery()
cmd.Connection.Close()
Next
好的,我终于找到了解决方法,这是一个有点长的过程,但基本上我将SELECT语句(有多行)加载到gridview表中,并使用for循环将其插入到insert into语句中。下面是我的代码: 在桌子上展示
Dim Adapter As New OleDbDataAdapter
Dim Data As New DataTable
Dim SQL As String
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Shantara Production IT.mdb")
Dim cmd As New OleDbCommand()
grdvmachincomp.Visible = false
SQL = "SELECT DISTINCT POH.BatchNo, SSCDD.ComponentID
FROM ([KN - ProductionOrderHeader] AS POH
INNER Join [FG - End Product Codes] AS EPC
On POH.ProductID = EPC.ProductID)
INNER Join([KN - ProductionOrderDetails] AS POD
INNER Join [FG - Style Size Comp Def Details] AS SSCDD
On POD.SizeID = SSCDD.SizeID)
On (POH.BatchNo = POD.BatchNo)
And (EPC.StyleID = SSCDD.StyleID)
WHERE POH.BatchNo = '" & BatchNo & "'"
con.Open()
cmd.Connection = con
cmd.CommandText = SQL
Adapter.SelectCommand = cmd
Adapter.Fill(Data)
grdvmachincomp.DataSource = Data
grdvmachincomp.DataBind()
cmd.Connection.Close()
插入到直通for循环中
For c As Integer = 0 To grdvmachincomp.Rows.Count - 1
Dim cmdstring As String
cmdstring = " INSERT INTO [KN - ProductionMachineAllocation] (BatchNo, ComponentID) VALUES('" & grdvmachincomp.Rows(c).Cells(0).Text & "', " & grdvmachincomp.Rows(c).Cells(1).Text & ");"
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Shantara Production IT.mdb")
Dim cmd As New OleDbCommand(cmdstring)
cmd.CommandType = CommandType.Text
cmd.Connection = con
cmd.Connection.Open()
cmd.ExecuteNonQuery()
cmd.Connection.Close()
Next
大多数数据库能够完全在数据库中更有效地完成所有这些工作。当然,在SQL Server中,我可以将整个过程归结为一个查询。Access有点不同,因为vbscript是它的过程语言,而不是更像t-sql的东西。也许还有一种方法可以做到这一点,但既然你的方法行之有效,我们至少可以专注于让它变得更好 GridView是一种视觉构造,它会占用额外的内存和资源。如果Access无法执行真正的插入/选择,则至少可以直接从上一个结果集中读取到插入中。您还可以通过使用参数并对所有插入重新使用单个打开连接来显著改进这一点:
Dim cnString As String=“Provider=Microsoft.ACE.OLEDB.12.0;数据源=| DataDirectory | \Shantara Production IT.mdb”
Dim SQLDown作为字符串=_
“选择不同的POH.BatchNo、SSCDD.ComponentID
从([KN-生产或装卸工]作为POH
内部连接[FG-最终产品代码]作为EPC
On POH.ProductID=EPC.ProductID)
内部连接([KN-生产订单明细]作为POD
内部连接[FG-样式尺寸组件定义详细信息]为SSCDD
在POD.SizeID=SSCDD.SizeID上)
打开(POH.BatchNo=POD.BatchNo)
和(EPC.StyleID=SSCDD.StyleID)
其中POH.BatchNo=?”
将SQLUp设置为字符串=_
“插入[KN-生产机械位置]
(BatchNo,ComponentID)
值(?,)”
Dim dt作为新数据表
使用con作为新的OLEDB连接(cnString)_
cmd作为新的OleDbCommand(SQLDown,con)
'此处猜测参数类型/长度。
'使用数据库中的实际列类型和大小
cmd.Parameters.Add(“@BatchNo”,OleDbType.VarWChar,10)。Value=BatchNo
con.Open()
dt.Load(cmd.ExecuteReader())
终端使用
使用con作为新的OLEDB连接(cnString)_
cmd作为新的OleDbCommand(SqlUp,con)
'再次猜测参数类型/长度
cmd.Parameters.Add(“@BatchNo”,OleDbType.VarWChar,10)
cmd.Parameters.Add(“@ComponentID”,OleDbType.Integer)
'连接是在循环*之外*管理的*。仅创建一个对象,仅与DB进行一次协商
con.Open()
对于dt.行中作为DataRow的每一行
cmd.Parameters(0).Value=行(0)
cmd.Parameters(1).Value=行(1)
cmd.ExecuteNonQuery()
下一个
终端使用
通常,对于任何ADO.Net提供程序,您都不会重复使用连接或命令对象。对于发送到DB的每个查询,您都需要一个新的连接对象,以允许连接池正常工作。在类似这样的紧密循环中为同一查询使用连接是少数例外之一
通过坚持使用活动DataReader,而不是首先将其加载到DataTable中,我可能能够进一步改进。这将允许我们避免将整个结果集加载到内存中。您一次只需要内存中的一条记录。这当然适用于Sql Server。然而,Access主要设计为单用户数据库。它真的不喜欢同时有多个活动连接,我也不确定它会有什么反应
能够以事务性的方式完成所有这些工作也很好,在这种情况下,永远不会有在循环中部分失败并被一半的更新卡住的风险。Sql Server将通过单个插入/选择查询或显式事务来处理此问题。但,再一次,这并不是设计访问的目的。它可能确实有办法做到这一点,但我对它不熟悉。大多数数据库能够完全在数据库中更有效地完成所有这些工作。当然,在SQL Server中,我可以将整个过程归结为一个查询。Access有点不同,因为vbscript是它的过程语言,而不是更像t-sql的东西。也许还有一种方法可以做到这一点,但既然你的方法行之有效,我们至少可以专注于让它变得更好 GridView是一种视觉构造,它会占用额外的内存和资源。如果Access无法执行真正的插入/选择,则至少可以直接从上一个结果集中读取到插入中。您还可以通过使用参数并对所有插入重新使用单个打开连接来显著改进这一点:
Dim cnString As String=“Provider=Microsoft.ACE.OLEDB.12.0;数据源=| DataDirectory | \Shantara Production IT.mdb”
Dim SQLDown作为字符串=_
“选择不同的POH.BatchNo、SSCDD.ComponentID
从([KN-生产或装卸工]作为POH
内部连接[FG-最终产品代码]作为EPC
On POH.ProductID=EPC.ProductID)
内部连接([KN-生产订单明细]作为POD
内部连接[FG-样式尺寸组件定义详图