Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server VBA大SQL查询-方法';从记录集复制';对象的';范围';失败_Sql Server_Oracle_Vba_Excel - Fatal编程技术网

Sql server VBA大SQL查询-方法';从记录集复制';对象的';范围';失败

Sql server VBA大SQL查询-方法';从记录集复制';对象的';范围';失败,sql-server,oracle,vba,excel,Sql Server,Oracle,Vba,Excel,下面发布的代码连接到oracle数据库,处理SQL查询并将结果表保存在新工作簿中。它最多可运行约200000行。但是,对于较大的数据集,当我尝试将数据从记录集对象复制到工作簿时,对象“范围”的方法“CopyFromRecordset”失败 dataWs.Range("A2").CopyFromRecordset dataset 有什么解决办法吗?我尝试在数据集的所有元素上循环,并将它们复制到工作表中,但是对于大型数据集,这需要非常长的时间。你有什么想法吗?我感谢你的帮助!下面是代码: Sub

下面发布的代码连接到oracle数据库,处理SQL查询并将结果表保存在新工作簿中。它最多可运行约200000行。但是,对于较大的数据集,当我尝试将数据从记录集对象复制到工作簿时,对象“范围”的方法“CopyFromRecordset”失败

dataWs.Range("A2").CopyFromRecordset dataset 
有什么解决办法吗?我尝试在数据集的所有元素上循环,并将它们复制到工作表中,但是对于大型数据集,这需要非常长的时间。你有什么想法吗?我感谢你的帮助!下面是代码:

Sub QueryExecute(sqlString, userPW, userID, serverName)
'Connect to database <serverName> using user name <userID> and 
'password <userPW> to process SQL query <sqlString> and save the
'query result in a new workbook

   Dim ConnStr As String
   Dim Cn As ADODB.Connection
   Dim dataset As ADODB.Recordset
   Dim dataWs As Worksheet
   Dim dataWb As Workbook
   Dim icols As Integer

   'Create new workbook that will hold the query result/table:
   Set dataWb = Excel.Application.Workbooks.Add
   Set dataWs = dataWb.Sheets(1)

   Application.Calculation = xlManual

   'Trim trailing/leading blanks from sqlString:
   sqlString = Trim(sqlString)

   'Create string for database connection:
   ConnStr = "UID=" & userID & ";PWD=" & userPW & ";DRIVER={Microsoft ODBC for Oracle};" _
                    & "SERVER=" & serverName & ";"

   'Connect to database:
   Set Cn = New ADODB.Connection

   On Error Resume Next 'Error handling in case connection does not work

   With Cn
     .ConnectionString = ConnStr
     .CursorLocation = adUseClient
     .Open
   End With

   'Error handling for failed connection:
   If Err.Number <> 0 Then

     dataWb.Close
     MsgBox "Connection to database failed. Check username and password."
     Exit Sub

   End If

   'Send SQL query to database:
   Set dataset = Cn.Execute(sqlString)

   'Error handling for failed query:
   If Err.Number <> 0 Then

     dataWb.Close
     MsgBox "SQL-query could not be processed."
     Exit Sub

   End If

   On Error GoTo 0

   'Copy column names in first row of table worksheet:
   For icols = 0 To dataset.Fields.count - 1
     dataWs.Cells(1, icols + 1).Value = dataset.Fields(icols).Name
   Next

   dataWs.Range(dataWs.Cells(1, 1), _
   dataWs.Cells(1, dataset.Fields.count)).Font.Bold = True 'Format column names

   'Copy data to workbook:
   '***THIS WILL FAIL FOR LARGE DATASETS***
   dataWs.Range("A2").CopyFromRecordset dataset 


   dataset.Close
   Cn.Close

   MsgBox "Query successful."

   Application.Calculation = xlCalculationAutomatic

End Sub
子查询执行(sqlString、userPW、userID、serverName)
'使用用户名和密码连接到数据库
'处理SQL查询并保存
'查询新工作簿中的结果
Dim ConnStr As字符串
Dim Cn作为ADODB.Connection
将数据集设置为ADODB.Recordset
将数据仓库作为工作表
Dim dataWb作为工作簿
作为整数的Dim-icol
'创建将保存查询结果/表的新工作簿:
设置dataWb=Excel.Application.Workbooks.Add
设置dataWs=dataWb.Sheets(1)
Application.Calculation=xlManual
'从sqlString修剪尾随/前导空格:
sqlString=Trim(sqlString)
'为数据库连接创建字符串:
ConnStr=“UID=“&userID&”PWD=“&userPW&”DRIVER={Microsoft ODBC for Oracle};”_
&“SERVER=“&serverName&;”
'连接到数据库:
Set Cn=New ADODB.Connection
错误时继续下一步“连接不工作时的错误处理”
与Cn
.ConnectionString=ConnStr
.CursorLocation=adUseClient
打开
以
'失败连接的错误处理:
如果错误号为0,则
dataWb.Close
MsgBox“与数据库的连接失败。请检查用户名和密码。”
出口接头
如果结束
'将SQL查询发送到数据库:
Set dataset=Cn.Execute(sqlString)
'失败查询的错误处理:
如果错误号为0,则
dataWb.Close
无法处理MsgBox“SQL查询”
出口接头
如果结束
错误转到0
'复制表格工作表第一行中的列名:
对于icols=0到dataset.Fields.count-1
单元格(1,icols+1).Value=dataset.Fields(icols).Name
下一个
dataWs.Range(dataWs.Cells(1,1)_
dataWs.Cells(1,dataset.Fields.count)).Font.Bold=True'格式列名
'将数据复制到工作簿:
“***对于大型数据集,这将失败***
dataWs.Range(“A2”).CopyFromRecordset数据集
数据集。关闭
Cn.Close
MsgBox“查询成功。”
Application.Calculation=xlCalculationAutomatic
端接头
根据-最大行数为1048576行乘以16384列。 鉴于此,操纵或检查一百万行是不现实的——我们可以假设电子表格正在汇总这些行吗? 如果是这样的话,您应该始终尽量减小返回Excel的记录集的大小。要做到这一点,您需要将数据的处理/汇总卸载到数据库中


这可以在SQL查询或返回SYS\u REFCURSOR的数据库过程中完成。这本质上是一个指向结果集的指针。

就像@OraNob所说的,通过在数据库端进行过滤、聚合和排序,最大限度地减少返回的数据量。如果必须检索大型数据集(以减少多个调用),可以考虑保持记录集打开,而只是用不同的数据子集所需的数据填充工作表。 如果记录集的行数超过了大约一百万行,则可以将结果写入多个工作表

我还建议使用GetRows函数,您需要对其进行转置,因为GetRows数组的尺寸是先列后行,Excel最好先行后列

此外,考虑到数据集的大小,并假设使用32位Office,您将无法依靠
Application.Worket.Transpose
来进行转置,因为您可能会耗尽内存,而且如果您自己进行转置,您可能需要小心使用内存。考虑打破转座和插入成批。

最后,记住将插入到工作表中作为范围,因为插入比逐个单元格快得多。例如:

Dim aData(1 to 10000, 1 to 16)
aRecordset = rst.GetRows(10000)
'Transpose the aRecordset into aData
'...
Sheet1.Range(Sheet1.cells(1,1),Sheet1.Cells(10000,16) = aData

您是否尝试过获取行数?但是,在将数组放入工作表之前,需要对其进行转置。我将数据分配给了数组,但是,对于大数据集,在尝试将GetRows分配给数组时,我会遇到内存不足的错误。在较大数据集的记录中是否有任何很长的文本值,而这些值在较小的数据集中不起作用?有关详细信息,请阅读:但将
recArray=rst.GetRows
更改为
如果不是rst.EOF,则为rst.MoveLast:rst.MoveFirst
然后
recArray=rst.GetRows(rst.RecordCount)