【问题标题】:VBA freezing while traversing recordset pulled from Redshift database遍历从 Redshift 数据库中提取的记录集时 VBA 冻结
【发布时间】:2018-08-02 16:35:39
【问题描述】:

我有这个 VBA 代码可以从 Redshift 数据库中提取相对少量的记录(大约 200 条)。

Dim cnDB As New ADODB.Connection
Dim RS As New ADODB.Recordset
Dim sqlContent As String

RS.ActiveConnection = cnDB
'RS.CursorLocation = adUseClient 'tried this, but results in recordcount "<data provider or other service returned an E_FAIL status>"
RS.Open sqlContent

x = 0
 For Each fld In RS.Fields
      With ws
        x = x + 1
        .Cells(1, x).Value = fld.Name
        colIndex.Add x, fld.Name
      End With
 Next fld

If Not RS.EOF Then
    RS.MoveFirst
Else
    Debug.Print "No Results Returned."
    Exit Sub
End If

'Populates row data
rN = 1
While Not RS.EOF
    rN = rN + 1
    With ws
        For Each fld In RS.Fields  'problem is occurring somewhere in here while processing 2nd record
            With .Cells(rN, colIndex(fld.Name))
                .Value = fld.Value
            End With
        Next fld
    End With
    RS.MoveNext
Wend

在我们从 Vertica 数据库迁移之前,这段代码没有问题。根据我在研究问题时发现的一些信息,我似乎遇到了麻烦,因为光标在 Redshift 中的工作方式不同,但如果这是我不知道如何解决的问题。

我在 DSN 连接选项中尝试了“使用声明/获取”而不是“将整个结果检索到内存中”,但我现在真的只是抓住了稻草。我可以看到并没有什么不同。

我直接对 Redshift 数据库运行了查询,它运行良好,返回了所有预期的记录。所以问题不存在。

在 VBA 中运行查询后,我看到记录集计数为 -1,但肯定有记录进入。当我在遍历字段时查看记录集时,一切看起来都很好,直到第二个字段中有几个字段记录集,然后我得到圆形光标,并且无限期地不能做任何其他事情。我必须杀死 Excel 并重新开始。

提前感谢您能给我的任何指点。

【问题讨论】:

  • 如果去掉底部的嵌套循环并调用CopyFromRecordset:ws.Cell(2, 1).CopyFromRecordset RS会发生什么?
  • 填充了整个第一行数据(31 个字段),但仅填充了其余 200 多条记录的前 2 个字段。
  • CopyFromRecordset 似乎可以工作,而其他记录的其余 29 个字段只是以某种方式从记录集中丢失。不幸的是,我无法在 Watch 中看到所有记录集的数据。
  • 这可以精确地发生。这 31 个字段的数据类型是什么?具有高位或最大小数位数的数字?
  • 里面有一些浮点数和时间戳。您认为将它们转换为其他东西可能会有所帮助吗?

标签: vba amazon-redshift


【解决方案1】:

感谢Parfait 的帮助!解决方案 (我认为 - 自从再次开始失败 - 请参阅下面的评论) 是首先替换整个段

'Populates row data
rN = 1
While Not RS.EOF
    rN = rN + 1
    With ws
        For Each fld In RS.Fields  'problem is occurring somewhere in here while processing 2nd record
            With .Cells(rN, colIndex(fld.Name))
                .Value = fld.Value
            End With
        Next fld
    End With
    RS.MoveNext
Wend

ws.Cells(2, 1).CopyFromRecordset RS

,然后我将查询中的浮点数转换为小数,并将时间戳转换为日期(不确定是否需要两次转换,但现在它正在工作,我不打算修改它)。

CAST(fieldThatWasFloat as DECIMAL(6,5)),
CAST(fieldThatWasTimestamp as DATE)

请注意,时间戳中丢失了一些细节,但这并不重要。可以肯定的是,它可以通过日期格式的一些小技巧来恢复。

【讨论】:

  • 这实际上又开始崩溃了。我回到尝试循环遍历字段,但是一旦遇到第二条记录中的空字段,执行似乎就冻结了。奇怪的是,空字段在第一条记录中处理得很好。达到第二条记录,找到一些填充的字段,处理良好,命中第一个空字段,不断转圈。
猜你喜欢
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多