切换Redshift ODBC Driver 1.0至2.0后VBA出现运行时错误,求解决
解决Redshift ODBC Driver 2.0 VBA CopyFromRecordset报错问题
问题背景
此前使用Redshift ODBC Driver 1.0时,以下VBA代码可正常将数据提取至Excel:
Sub Query_Data_driver_1.0 () Dim conn As New ADODB.Connection Dim rs As New ADODB.Recordset Set conn = New ADODB.Connection conn.ConnectionString = "DRIVER={Amazon Redshift ODBC Driver (x64)}; Server=xx; Database=xx; UID=xx; PWD=xx;" conn.Open strSQL = Sheet1.Shapes("SqlQuery1").OLEFormat.Object.Text Set rs = New ADODB.Recordset rs.Open strSQL, conn, adOpenStatic Sheet1.Range("A1").CopyFromRecordset rs rs.Close conn.Close End Sub
适配Redshift ODBC Driver 2.0后,修改了以下代码(多数文件运行正常):
Sub Query_Data_driver_2.0 () Dim conn As New ADODB.Connection Dim rs As New ADODB.Recordset Set conn = New ADODB.Connection conn.ConnectionString = "DRIVER={Amazon Redshift ODBC Driver (x64)}; Server=xx; Database=xx; UID=xx; PWD=xx;" conn.CursorLocation = adUseClient conn.Open strSQL = Sheet1.Shapes("SqlQuery1").OLEFormat.Object.Text Set rs = New ADODB.Recordset rs.Open strSQL, conn, adOpenStatic, adLockReadOnly Sheet1.Range("A1").CopyFromRecordset rs rs.Close conn.Close End Sub
但某一文件执行Sheet1.Range("A1").CopyFromRecordset rs时,出现错误:Run-time error '-2147217883 (80040e25)'
解决方案
处理特殊数据类型
Redshift Driver 2.0对部分数据类型的解析逻辑与1.0不同,比如TIMESTAMP WITH TIME ZONE、BYTEA、超大精度数值等,CopyFromRecordset无法直接兼容。可在SQL查询中转换这些类型:- 时间类型转字符串:
TO_CHAR(your_time_column, 'YYYY-MM-DD HH24:MI:SS') AS your_time_column - 二进制类型转BASE64字符串:
ENCODE(your_bytea_column, 'base64') AS your_bytea_column - 超大数值转DECIMAL或字符串:
CAST(your_large_num_column AS DECIMAL(38,0)) AS your_large_num_column
- 时间类型转字符串:
调整游标与锁参数
当前的客户端游标+静态游标组合可能在特定数据集下触发兼容性问题,尝试修改:- 改用仅向前游标:
rs.Open strSQL, conn, adOpenForwardOnly, adLockReadOnly - 移除客户端游标设置,使用服务器端游标:
' 注释掉该行 ' conn.CursorLocation = adUseClient
- 改用仅向前游标:
增加空记录集判断
若查询返回空记录集,CopyFromRecordset也可能抛出错误,添加前置判断:If Not rs.EOF And Not rs.BOF Then Sheet1.Range("A1").CopyFromRecordset rs Else ' 可选:提示空结果 ' MsgBox "查询无数据返回" End If优化ODBC连接参数
在连接字符串中添加兼容参数,强制Driver 2.0使用与1.0接近的行为:conn.ConnectionString = "DRIVER={Amazon Redshift ODBC Driver (x64)}; Server=xx; Database=xx; UID=xx; PWD=xx; UseDeclareFetch=0; StringAsLongVarchar=1;"UseDeclareFetch=0:禁用声明式取数,匹配Driver 1.0的取数逻辑StringAsLongVarchar=1:将长字符串映射为VARCHAR类型,避免类型不兼容
清理目标区域格式
若Sheet1的目标区域存在合并单元格、数据验证、特殊条件格式等,会导致CopyFromRecordset失败,提前清空区域:' 清空当前工作表所有单元格内容与格式 Sheet1.Cells.Clear Sheet1.Range("A1").CopyFromRecordset rs
内容的提问来源于stack exchange,提问作者Michi
相关产品推荐
相关产品推荐

