简体   繁体   English

在 VBA 中使用 ADO 连接到 PostgreSQL

[英]Using ADO in VBA to connect to PostgreSQL

I am having trouble finding clear and reliable examples of connecting to a PostgreSQL database from Excel using VBA ADO.我无法找到使用 VBA ADO 从 Excel 连接到 PostgreSQL 数据库的清晰可靠示例。 Admittedly, I am new to VBA and most examples and tutorials are very Access or MSSQL centered.诚然,我是 VBA 新手,大多数示例和教程都非常以 Access 或 MSSQL 为中心。 (I work mostly in Ruby, Rails, Perl and PostgreSQL.) (我主要使用 Ruby、Rails、Perl 和 PostgreSQL。)

I am looking for code to connect and return a simple query (SELECT * FROM customers;) to an Excel sheet.我正在寻找代码来连接并返回一个简单的查询 (SELECT * FROM customers;) 到 Excel 工作表。 Connection parameters (server ip, user, pass, database) are located within cells in a separate worksheet.连接参数(服务器 ip、用户、密码、数据库)位于单独工作表中的单元格内。

I appreciate your help and patience.感谢您的帮助和耐心。

Code:代码:

Sub ConnectDatabaseTest()
Dim cnn As ADODB.connection
Dim cmd As ADODB.Command
Dim param As ADODB.Parameter
Dim xlSheet As Worksheet
Dim rs As ADODB.Recordset
Dim sConnString As String
Dim i As Integer

' Connection Parameters
Dim strUsername As String
Dim strPassword As String
Dim strServerAddress As String
Dim strDatabase As String
' User:
strUsername = Sheets("CONFIG").Range("B4").Value
' Password:
strPassword = Sheets("CONFIG").Range("B5").Value
' Server Address:
strServerAddress = Sheets("CONFIG").Range("B6").Value
' Database
strDatabase = Sheets("CONFIG").Range("B3").Value

Set xlSheet = Sheets("TEST")
xlSheet.Activate
Range("A3").Activate
Selection.CurrentRegion.Select
Selection.ClearContents
Range("A1").Select

Set cnn = New ADODB.connection
sConnString = "DRIVER={PostgreSQL Unicode};DATABASE=" & strDatabase & ";SERVER=" & strServerAddress & _
    ";UID=" & strUsername & ";PWD=" & strPassword
cnn.Open sConnString

cmd.ActiveConnection = cnn

Dim strSQL As String
strSQL = "SELECT * FROM customers"

cmd.CommandType = ADODB.CommandTypeEnum.adCmdText
cmd.ActiveConnection = cnn
cmd.CommandText = strSQL
...

It seems to break here: cmd.ActiveConnection = cnn它似乎在这里中断:cmd.ActiveConnection = cnn

EDIT: added sample code.编辑:添加了示例代码。

EDIT: sConnString gets set to:编辑:sConnString 设置为:

DRIVER={PostgreSQL35W};DATABASE=my_database;SERVER=1.2.3.4;UID=analyst;PWD=sekrit

UPDATE 2/7: I changed the 'DRIVER' parameter in the connection string:更新 2/7:我更改了连接字符串中的“DRIVER”参数:

    sConnString = "DRIVER={PostgreSQL Unicode};DATABASE=" & strDatabase & ";SERVER=" & strServerAddress & _
    ";UID=" & strUsername & ";PWD=" & strPassword & ";"

...and I get a different error: 'Run-time error 91: Object variable or With block variable not set' ...我得到一个不同的错误:'运行时错误 91:对象变量或块变量未设置'

Hm.嗯。 Ideas?想法?

I wan't using a DSN as I am using an ODBC driver as opposed to OLE DB.我不想使用 DSN,因为我使用的是 ODBC 驱动程序而不是 OLE DB。 By referencing a DSN, the above code works with very few changes.通过引用 DSN,上面的代码只需很少的更改即可工作。

See this question for how I found the answer once I began to suspect OLE DB/ODBC to the issue.请参阅此问题,了解一旦我开始怀疑 OLE DB/ODBC 的问题,我是如何找到答案的。 Does ADO work with ODBC drivers or only OLE DB providers? ADO 是与 ODBC 驱动程序一起工作还是仅与 OLE DB 提供程序一起工作?

New Code here:新代码在这里:

Sub GetCustomers()
Dim oConn As New ADODB.connection
Dim cmd As New ADODB.Command
' Connection Parameters
Dim strUsername As String
Dim strPassword As String
Dim strServerAddress As String
Dim strDatabase As String
' User:
strUsername = Sheets("CONFIG").Range("B4").Value
' Password:
strPassword = Sheets("CONFIG").Range("B5").Value
' Server Address:
strServerAddress = Sheets("CONFIG").Range("B6").Value
' Database
strDatabase = Sheets("CONFIG").Range("B3").Value


oConn.Open "DSN=my_system_dsn;" & _
    "Database=" & strDatabase & ";" & _
    "Uid=" & strUsername & ";" & _
    "Pwd=" & strPassword

Set xlSheet = Sheets("CUSTOMERS")
xlSheet.Activate
Range("A3").Activate
Selection.CurrentRegion.Select
Selection.ClearContents
Range("A1").Select

Dim strSQL As String
strSQL = "SELECT * FROM customers"

cmd.CommandType = ADODB.CommandTypeEnum.adCmdText
cmd.ActiveConnection = oConn
cmd.CommandText = strSQL

Set rs = New ADODB.Recordset
Set rs = cmd.Execute

For i = 1 To rs.Fields.Count
    ActiveSheet.Cells(3, i).Value = rs.Fields(i - 1).Name
Next i

xlSheet.Range(xlSheet.Cells(3, 1), _
    xlSheet.Cells(3, rs.Fields.Count)).Font.Bold = True

ActiveSheet.Range("A4").CopyFromRecordset rs

xlSheet.Select
Range("A3").Select
Selection.CurrentRegion.Select
Selection.Columns.AutoFit
Range("A1").Select

rs.Close
oConn.Close

Set cmd = Nothing
Set param = Nothing
Set rs = Nothing
Set cnn = Nothing
Set xlSheet = Nothing
End Sub

The System DSN is configured to use the PostgreSQL Unicode driver.系统 DSN 配置为使用 PostgreSQL Unicode 驱动程序。 I chose not to use OLE DB even though there is a provider available.即使有可用的提供程序,我也选择不使用 OLE DB。 If you look at PGFoundry, you will see it has many problems and has not been updated in several years.如果你查看PGFoundry,你会发现它有很多问题,而且几年没有更新。

In the original Code, "PostgreSQL35W" is a DSN name which included the default host and port.在原始代码中,“PostgreSQL35W”是一个包含默认主机和端口的 DSN 名称。 When you changed to "PostgreSQL Unicode", it is a driver and your connection string is lacking the value for the port.当您更改为“PostgreSQL Unicode”时,它是一个驱动程序并且您的连接字符串缺少端口值。 Remember to access PostgreSQL directly from driver, you need at least 5 parameters:记住直接从驱动访问PostgreSQL,至少需要5个参数:

  • host主持人
  • port港口
  • userid用户身份
  • password密码
  • database数据库

If you are using DSN, some parameters may be defined as default.如果您使用的是 DSN,某些参数可能会被定义为默认值。

不确定实际数据库连接的详细信息,但是您的语句有一个简单但常见的错误:在处理对象时需要使用“set”:

set cmd.ActiveConnection = cnn

设置 cmd = 新建 ADODB.Command cmd.ActiveConnection = cnn

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM