帮助!将数据从一列复制到类似记录集中的同一列时出错

发布于 2024-10-10 22:15:25 字数 680 浏览 4 评论 0原文

我有一个例程,它读取一个记录集,并在类似的记录集中添加/更新行。该例程首先将列复制到新记录集:

这是创建新记录集的代码..

For X = 1 To aRS.Fields.Count
    mRS.Fields.Append aRS.Fields(X - 1).Name, aRS.Fields(X - 1).Type, aRS.Fields(X - _
          1).DefinedSize, aRS.Fields(X - 1).Attributes
Next X

非常简单。注意名称、类型、定义大小和大小的复制。属性...

在代码的更下方,(并且没有任何内容可以修改之间的任何列..)我将一行的值复制到新记录集中的一行,如下所示:

 For C = 1 To aRS.Fields.Count
     mRS.Fields(C - 1) = aRS.Fields(C - 1)
 Next C

当它到达最后一列时这是一个数字,它会显示“多步操作生成错误”消息。

我知道 MS 说这是由提供程序生成的错误,在本例中为 ADO 2.8。此时也没有与数据库的开放连接。

我正在拉我剩下的一点头发......(此时我并不真正关心列索引在一个循环中是“X”而在另一个循环中是“C”......我当我解决真正的问题后会更改它......)

I have a routine which reads one recordset, and adds/updates rows in a similar recordset. The routine starts off by copying the columns to a new recordset:

Here's the code for creating the new recordset..

For X = 1 To aRS.Fields.Count
    mRS.Fields.Append aRS.Fields(X - 1).Name, aRS.Fields(X - 1).Type, aRS.Fields(X - _
          1).DefinedSize, aRS.Fields(X - 1).Attributes
Next X

Pretty straight forward. Notice the copying of the name, Type, DefinedSize & Attributes...

Further down in the code, (and there's nothing that modifies any of the columns between.. ) I'm copying the values of a row to a row in the new recordset as such:

 For C = 1 To aRS.Fields.Count
     mRS.Fields(C - 1) = aRS.Fields(C - 1)
 Next C

When it gets to the last column which is a numeric, it craps with the "Mutliple-Step Operation Generated an error" message.

I know that MS says this is an error generated by the provider, which in this case is ADO 2.8. There is no open connect to the DB at this point in time either.

I'm pulling what little hair I have left over this one... (and I don't really care at this point that the column index is 'X' in one loop & 'C' in the other... I'll change it later when I get the real problem fixed...)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ま柒月 2024-10-17 22:15:25

在打开合成记录集之前,您必须为 adDecimaladNumeric 字段设置 PrecisionNumericScale 仅供参考

For X = 1 To aRS.Fields.Count
    With aRS.Fields(X - 1)
        Select Case .Type
        Case adChar, adWChar, adBinary, _
                adVarChar, adVarWChar, adVarBinary, _
                adLongVarChar, adLongVarWChar, adLongVarBinary
            mRS.Fields.Append .Name, .Type, .DefinedSize, .Attributes
        Case adDecimal, adNumeric
            mRS.Fields.Append .Name, .Type, , .Attributes
            mRS.Fields(mRS.Fields.Count - 1).Precision = .Precision
            mRS.Fields(mRS.Fields.Count - 1).NumericScale = .NumericScale
        Case Else
            mRS.Fields.Append .Name, .Type, , .Attributes
        End Select
    End With
Next

:您可能获取一个记录集,其中的字段没有数据库中的名称,例如

SELECT 5, 'No name'

,但 ADO 不允许在 Append 方法上使用空名称。您还可能从数据库中获取包含重复字段的记录集,例如,

SELECT 5 AS Col, 'Second' AS Col

在您的情况下,该记录集也会在 Append 上崩溃。

You have to set Precision and NumericScale for adDecimal and adNumeric fields before opening synthetic recordset like this

For X = 1 To aRS.Fields.Count
    With aRS.Fields(X - 1)
        Select Case .Type
        Case adChar, adWChar, adBinary, _
                adVarChar, adVarWChar, adVarBinary, _
                adLongVarChar, adLongVarWChar, adLongVarBinary
            mRS.Fields.Append .Name, .Type, .DefinedSize, .Attributes
        Case adDecimal, adNumeric
            mRS.Fields.Append .Name, .Type, , .Attributes
            mRS.Fields(mRS.Fields.Count - 1).Precision = .Precision
            mRS.Fields(mRS.Fields.Count - 1).NumericScale = .NumericScale
        Case Else
            mRS.Fields.Append .Name, .Type, , .Attributes
        End Select
    End With
Next

FYI: you might be get a recordset with a field that has no name from the database e.g.

SELECT 5, 'No name'

but ADO will not allow an empty name on Append method. You might also get a recordset with duplicate fields from the database e.g.

SELECT 5 AS Col, 'Second' AS Col

which in your case will bomb out on Append too.

滥情空心 2024-10-17 22:15:25

猜测 2:正确的行应该是

mRS.Fields(C - 1).value = aRS.Fields(C - 1).value

我的猜测是您有一个 null 并且您没有正确对待 dbnull 类型。

Guess 2 : the correct line should be

mRS.Fields(C - 1).value = aRS.Fields(C - 1).value

My guess is you have have a null and you are not treating the dbnull type right.

我的黑色迷你裙 2024-10-17 22:15:25

请参阅我关于寻找替代方法的评论,但直接的答案是需要设置 Field 对象的 PrecisionNumericScale 属性。这是错误的重现,取消注释这两行以修复错误:

Sub bfgosdb()

  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")
  With cat
    .Create _
        "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.mdb"
    With .ActiveConnection

      Dim Sql As String

      Sql = _
          "CREATE TABLE Test1 " & vbCr & "(" & vbCr & " col1 VARCHAR(255)," & _
          " " & vbCr & " col2 INTEGER, " & vbCr & " col3 DECIMAL(19,4)" & vbCr & ");"
      .Execute Sql

      Sql = _
          "INSERT INTO Test1 (col1, col2, col3) " & vbCr & "VALUES" & _
          " (" & vbCr & "'128000 and some change', " & vbCr & "128000, " & vbCr & "128000.1234" & vbCr & ");"
      .Execute Sql

      Sql = _
          "INSERT INTO Test1 (col1, col2, col3) " & vbCr & "VALUES" & _
          " (" & vbCr & "NULL, " & vbCr & "NULL, " & vbCr & "NULL " & vbCr & ");"
      .Execute Sql

      Sql = _
          "SELECT T11.col1, T11.col2, T11.col3 " & vbCr & "  FROM" & _
          " Test1 AS T11;"

      Dim aRS
      Set aRS = .Execute(Sql)

      Dim mRS
      Set mRS = CreateObject("ADODB.Recordset")

      Dim X As Long
      For X = 1 To aRS.Fields.Count
          mRS.Fields.Append aRS.Fields(X - 1).Name, aRS.Fields(X - 1).Type, aRS.Fields(X - _
                1).DefinedSize, aRS.Fields(X - 1).Attributes

'          mRS.Fields(mRS.Fields.Count - 1).NumericScale = aRS.Fields(X - 1).NumericScale  '
'          mRS.Fields(mRS.Fields.Count - 1).Precision = aRS.Fields(X - 1).Precision  '
      Next X

      mRS.Open

      Do While Not aRS.EOF

        mRS.AddNew

        Dim C As Long
        For C = 1 To aRS.Fields.Count
            mRS.Fields(C - 1) = aRS.Fields(C - 1)
        Next C

        aRS.MoveNext

      Loop

    End With
    Set .ActiveConnection = Nothing
  End With
End Sub

Please see my comments about finding an alternative approach but the straight answer is the Field objects' Precision and NumericScale properties need to be set. Here's a repro of your error, uncomment the two lines to fix the error:

Sub bfgosdb()

  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")
  With cat
    .Create _
        "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.mdb"
    With .ActiveConnection

      Dim Sql As String

      Sql = _
          "CREATE TABLE Test1 " & vbCr & "(" & vbCr & " col1 VARCHAR(255)," & _
          " " & vbCr & " col2 INTEGER, " & vbCr & " col3 DECIMAL(19,4)" & vbCr & ");"
      .Execute Sql

      Sql = _
          "INSERT INTO Test1 (col1, col2, col3) " & vbCr & "VALUES" & _
          " (" & vbCr & "'128000 and some change', " & vbCr & "128000, " & vbCr & "128000.1234" & vbCr & ");"
      .Execute Sql

      Sql = _
          "INSERT INTO Test1 (col1, col2, col3) " & vbCr & "VALUES" & _
          " (" & vbCr & "NULL, " & vbCr & "NULL, " & vbCr & "NULL " & vbCr & ");"
      .Execute Sql

      Sql = _
          "SELECT T11.col1, T11.col2, T11.col3 " & vbCr & "  FROM" & _
          " Test1 AS T11;"

      Dim aRS
      Set aRS = .Execute(Sql)

      Dim mRS
      Set mRS = CreateObject("ADODB.Recordset")

      Dim X As Long
      For X = 1 To aRS.Fields.Count
          mRS.Fields.Append aRS.Fields(X - 1).Name, aRS.Fields(X - 1).Type, aRS.Fields(X - _
                1).DefinedSize, aRS.Fields(X - 1).Attributes

'          mRS.Fields(mRS.Fields.Count - 1).NumericScale = aRS.Fields(X - 1).NumericScale  '
'          mRS.Fields(mRS.Fields.Count - 1).Precision = aRS.Fields(X - 1).Precision  '
      Next X

      mRS.Open

      Do While Not aRS.EOF

        mRS.AddNew

        Dim C As Long
        For C = 1 To aRS.Fields.Count
            mRS.Fields(C - 1) = aRS.Fields(C - 1)
        Next C

        aRS.MoveNext

      Loop

    End With
    Set .ActiveConnection = Nothing
  End With
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文