使用ms访问db

时间:2017-11-13 12:53:13

标签: 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] (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访问不支持ROW_NUMBER()所以我需要找到另一个遍历每一行,因为ms访问不支持插入select语句中的多行插入,比如我的任何建议我的问题?

2 个答案:

答案 0 :(得分:1)

大多数数据库都能够在数据库中更有效地完成所有这些工作。当然,在SQL Server中,我可以将整个内容归结为单个查询。访问有点不同,因为vbscript是它的过程语言,而不是更像t-sql的东西。仍然有可能做到这一点,但是既然你有所作为,我们至少可以专注于做得更好。

GridViews是可视化构造,会占用额外的内存和资源。如果Access不会执行真正的INSERT / SELECT,您至少可以直接从先前的结果集读取到插入中。您还可以通过使用参数并为所有插入重用单个打开连接来显着改善这一点:

Dim cnString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Shantara Production IT.mdb"
Dim SQLDown As String = _
     "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 = ? "
Dim SQLUp As String = _
    " INSERT INTO [KN - ProductionMachineAllocation] 
      (BatchNo, ComponentID) 
       VALUES( ?, ? )"

Dim dt As New DataTable
Using con As New OleDbConnection(cnString), _
      cmd As New OleDbCommand(SQLDown, con)

    'Guessing at parameter type/length here.
    'Use the actual column type and size from your DB
    cmd.Parameters.Add("@BatchNo", OleDbType.VarWChar, 10).Value = BatchNo

    con.Open()
    dt.Load(cmd.ExecuteReader())
End Using

Using con As New OleDbConnection(cnString), _
      cmd As New OleDbCommand(SqlUp, con)

    'Guessing at parameter types/lengths again
    cmd.Parameters.Add("@BatchNo", OleDbType.VarWChar, 10)
    cmd.Parameters.Add("@ComponentID", OleDbType.Integer)

    'Connection is managed *outside of the loop*. Only one object created, only one negotiation with DB
    con.Open()
    For Each row As DataRow In dt.Rows
          cmd.Parameters(0).Value = row(0)
          cmd.Parameters(1).Value = row(1)
          cmd.ExecuteNonQuery()
    Next
End Using

通常,对于任何ADO.Net提供程序,您都重新使用您的连接或命令对象。您希望为发送到数据库的每个查询提供一个新的连接对象,以允许连接池正常工作。对于相同的查询,在这样的紧密循环中使用连接是少数例外之一。

我可以通过坚持使用活动DataReader进一步改进,而不是先将其加载到DataTable中。这将允许我们避免将整个结果集加载到内存中。你一次只能在内存中需要一条记录。当然这适用于Sql Server。但是,Access主要设计为单用户数据库。它一下子并不真正喜欢多个活动连接,我不确定它会如何响应。

答案 1 :(得分:0)

好的我终于找到了解决它的方法,这是一个很长的过程,但基本上我将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