Access 连接 PostgreSQL


摘要: Access 通过官方 psqlODBC 驱动连接 PostgreSQL,从装驱动到增删改查,一步一步在本机跑通,最后说几个 PostgreSQL 特有的注意点。access开发|access培训|access框架|请添加edonsoft。

5.png

Hi,大家好!

Access 连 SQL Server 我写过,连 MySQL 我写过,直接调 sqlite3.dll 操作 SQLite 我也写过,PostgreSQL 这块一直空着,今天把这一篇补上。

先说说为什么值得给 PostgreSQL 单独写一篇。做 Access 后台升级,以前基本就是 SQL Server 和 MySQL 两个选项,这几年 PostgreSQL 明显挤进来了,而且有它自己的道理:

  • 许可证干净。 BSD 风格,商用免费,没有 SQL Server 按核心收费那本账;MySQL 虽然也有免费的社区版,但它在 Oracle 手里,GPL 加商业双许可,真到商用分发的场景反而要多想一下。PostgreSQL 拿来就用,不用琢磨授权。

  • 功能上更像「小号 SQL Server」而不是 MySQL。 窗口函数、CTE、物化视图、真正严格的事务和约束检查,这些 SQL Server 用户习以为常的东西 PostgreSQL 全有,而 MySQL 是近几个版本才陆续补齐的。从 SQL Server 迁过来的人写 PG 的 SQL,比写 MySQL 顺手得多。

当然它也不是全面胜出:Windows 生态的顺滑程度不如 SQL Server,图形管理工具 pgAdmin 比 SSMS 难用不少,国内的中文资料也比 MySQL 少。但作为 Access 的免费后台,它是很能打的一个选项。

连起来并不麻烦。PostgreSQL 有官方维护的 ODBC 驱动 psqlODBC,装上之后用 ADO 连,代码写法和连 SQL Server 基本一样。整个过程我都在本机做:PostgreSQL 装在开发机上,连 localhost,不涉及服务器配置,跟着做就能跑通。

第一步:安装 psqlODBC 驱动

驱动的项目主页是 odbc.postgresql.org,安装包在 PostgreSQL 官方的 FTP 目录里:

https://www.postgresql.org/ftp/odbc/releases/

进去选最新的 REL-XX_XX_XXXX 目录下载。注意早年那个 /ftp/odbc/versions/msi/ 的路径已经不维护了,网上很多老文章还在贴那个链接。

下载哪个位数?跟 Office 走,不是跟 Windows 走。 Access 里按 Ctrl+G 打开立即窗口,敲一句:

? IIf(Win64, "64位 Office", "32位 Office")

是什么就下什么。msi 一路默认装完。

装完验证一下:打开 ODBC 数据源管理器(开始菜单搜「ODBC」),切到「驱动程序」选项卡,能看到 PostgreSQL UnicodePostgreSQL ANSI 两条就说明装好了。中文环境统一用 PostgreSQL Unicode,ANSI 那个会出乱码,别碰。

如果驱动明明装了却看不到,多半是位数没对上——64 位系统有两个 ODBC 管理器,System32 下面是 64 位的,SysWOW64 下面才是 32 位的,去另一个里面找找。

第二步:添加 ADO 引用

打开 VBA 编辑器,菜单「工具 → 引用」,勾上:

Microsoft ActiveX Data Objects 6.1 Library

不勾的话,代码里的 ADODB.Connection 编译时会报「用户定义类型未定义」。

第三步:连接数据库

新建一个标准模块,命名 modPG,先写连接部分:

image.png

连接串里的 BoolsAsChar=0 是特意加的:psqlODBC 默认把 boolean 列当字符返回,VBA 拿到的是 "1""0" 两个字符串而不是 TrueFalse,加了这个参数才映射成正常的布尔值。

写完在立即窗口测一下:

? PG_Connect().State

返回 1 就是通了。报错的话,先看密码对不对,再确认 PostgreSQL 的 Windows 服务有没有在跑。

第四步:建表

演示用一张最简单的员工表。写一个过程执行 DDL:

image.png

serial 是 PostgreSQL 的自增整数,等价于 Access 的「自动编号」、SQL Server 的 IDENTITY

第五步:插入(Create)

写入一律走参数,不要拼字符串——名字里带个英文单引号 SQL 就断了,而且拼字符串就是注入口子。ODBC 的参数占位符是 ?

image.png

要连插多条,用事务包起来,速度差别很大:

image.png

第六步:查询(Read)

image.png

立即窗口输出:

 1            张三          技术部        15000
 2            李四          财务部        12000
 3            王五          市场部        18000

第七步:更新和删除(Update / Delete)

和插入一样走 Command 加参数,Execute 的第一个参数能拿回受影响的行数,用它判断有没有真的改到:

image.png

到这里,增删改查就全跑通了。

PostgreSQL 几个特殊的注意点

上面的代码换成 SQL Server 几乎原样能用。

标识符会被折成小写。 不加双引号的表名、字段名,PostgreSQL 一律转成小写存储。你写 CREATE TABLE T_Employee (UserName text),实际建出来的是 t_employeeusername。反过来,如果建表时带了双引号(比如用别的工具导过来的 "UserName"),以后每次引用都必须带引号,VBA 字符串里还得写成两个双引号,很折磨。建议库里统一小写加下划线,一劳永逸。

日期不认井号。 Access SQL 里的 #2024-03-15# 到 PostgreSQL 这边直接语法错误。走参数没这个问题;要拼字符串就用 '2024-03-15' 这种单引号加 ISO 格式。

boolean 是真正的布尔类型。 SQL 里写 WHERE is_active = true,不是 SQL Server 那种 = 1。取回 VBA 这边是不是 True/False,取决于连接串里有没有 BoolsAsChar=0,前面第三步已经加了。

常用函数和语法对照。 从 Access 查询往 PG 搬 SQL 时,这几个最常撞上:

AccessPostgreSQL
SELECT TOP 10LIMIT 10
Nz(x, 0)COALESCE(x, 0)
字段1 & 字段2字段1 || 字段2
Now() / Date()now() / current_date
IIf(a, b, c)CASE WHEN a THEN b ELSE c END

numeric 取回来是 Decimal。 numeric(10,2) 到 VBA 这边是 Decimal 子类型的 Variant,参与计算没问题,但要写进 Access 本地表的货币字段时记得 CCur 转一下。

小结

本机跑通这套一共就四件事:装驱动、加 ADO 引用、写连接串、SQL 走参数。之后要连局域网服务器,把 PG_HOSTlocalhost 改成服务器地址就行——那时候如果连不上,问题基本出在服务器端的 pg_hba.conf 和防火墙,不在 VBA 代码上,这个以后有机会再展开写。

测试环境:Access 2019 / 365,psqlODBC 16.x,本机安装的 PostgreSQL 16,Windows 10 / 11


如果你手上也有一个 Access 前端要接 PostgreSQL,欢迎公众号后台留言,我看到了会回。

技术培训

  • Access VBA 从入门到精通(线上/线下均可)

  • Access + SQL Server 企业级开发实战

  • Access 系统性能优化与架构设计

  • AI + Access 融合开发专题培训

定制开发

  • 企业 ERP / CRM / 进销存 / WMS / MES 等系统开发

  • 旧 Access 系统升级、性能优化与架构重构

  • AI 能力集成到现有 Access 业务系统

技术支持

  • 代码审查与重构建议

  • 疑难问题远程诊断

  • 一对一技术辅导

联系方式:

References

[1] www.edonsoft.com: http://www.edonsoft.com

6.png