2

我想分析我的数据库,并通过"sp_MSforeachtable 'EXECUTE sp_spaceused [?];';"从 ADODB 命令或记录集执行将每个表的结果输入 MS Excel 工作表,然后使用 CopyFromRecordset 将结果输出到 Excel。

这是我正在使用的代码:

Sub analyseHermesDB()
Dim oConn As Object, oRec As Object, oField As Object, iIndx As Integer

' sp_MSforeachtable 'EXECUTE sp_spaceused [?];';
Set oConn = CreateObject("ADODB.Connection")
Set oRec = CreateObject("ADODB.Recordset")

oConn.Open "FILE NAME=" & ThisWorkbook.Path & "\conn.udl"
    With oRec
        .activeconnection = oConn
        .Source = "sp_MSforeachtable 'EXECUTE sp_spaceused [?];';"
        .cursorlocation = 3
        .Open
        For iIndx = 0 To .fields.Count - 1
            ActiveCell.Offset(0, iIndx).Value = .fields(iIndx).Name
        Next
        Do Until .EOF
            ActiveCell.Offset(.absoluteposition, 0).CopyFromRecordset oRec
            .movenext
        Loop
        ActiveCell.Offset(0, 1).Value = .RecordCount
        .Close
    End With

End Sub

问题是这样的:当我"sp_MSforeachtable 'EXECUTE sp_spaceused [?];';"在 SQL Server 2008 Management Studio 中执行时,我得到每个表的一个结果集。

我只从使用 ADO 的呼叫中返回一个记录集

我究竟做错了什么?我应该尝试获取一组记录集,还是执行sp_MSforeachtable以获取表列表然后EXECUTE sp_spaceused [?];'为每个表执行?

4

2 回答 2

3

sp_MSforeachtable 返回多个结果集,您需要以这种方式使用它们

但是,您可以使用一些简单的 SQL 来实现您想要的,而不是
sp_spaceused 在内部使用类似的 SQL...

随意调整,这是我使用的脚本的精确复制/粘贴

SELECT
    o.name,
    SUM(ps.reserved_page_count)/128.0 AS ReservedMB, 
    SUM(ps.used_page_count)/128.0 AS UsedMB
FROM
    sys.objects o
    JOIN
    sys.dm_db_partition_stats ps ON o.object_id = ps.object_id
WHERE
    OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0
GROUP BY
    o.name
ORDER BY
    SUM(ps.reserved_page_count) DESC
于 2013-05-16T11:40:53.640 回答
1

我只从使用 ADO 的呼叫中返回一个记录集

这不是真的,您只是在评估一个记录集。用于NextRecordset获取下一个记录集。

Visual Basic 概念

运行返回多个结果集的存储过程

Private Sub MultipleRSButton_Click()
   Dim rs As New ADODB.Recordset
   sql = "Select * from Authors Where year_born is not null; " _
    & "Select * from Authors where year_born is  null"
   rs.Open sql, cn
   Do
      i = MsgBox("Ready for results?", vbYesNoCancel)
      If i = vbYes Then
         ADOGrid1.ShowData rs
         Set rs = rs.NextRecordset
      End If
   Loop Until rs.State = adStateClosed
End Sub

注意Set rs = rs.NextRecordset

但是出于所有意图和目的,gbn答案可能更好;它不依赖于未记录的存储过程。

于 2013-05-16T11:40:46.087 回答