马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?站点注册
×
PowerBuilder 9 + SQL Server 2008 升级到 PowerBuilder 12.5 + SQL Server 2022 全面规划与注意事项
本文面向正在使用「PB9 + MSSQL2008」老旧技术栈、计划整体迁移到「PB12.5 + MSSQL2022」的团队,给出一套可落地的升级规划、逐项的注意事项清单与排错预案。升级目标是"平滑迁移、行为一致、风险可控",不是重写系统。 阅读说明
① 适用版本:客户端由 PowerBuilder 9(ANSI)升级到 PowerBuilder 12.5(Classic,Unicode);数据库由 SQL Server 2008(兼容级别 100)升级到 SQL Server 2022(兼容级别 160)。
② 支持数据库:Microsoft SQL Server 2008(含 R2)/ SQL Server 2022(含 Express / Standard / Enterprise)。
③ 操作系统与环境要求:开发机 Windows 7+/10/11、需安装 PB12.5 与对应数据库接口运行库(PBVM125 系列、PBMSOLEDBSQL 接口);数据库服务器需 Windows Server 2016+(SQL2022 仅 64 位、要求 .NET 4.7.2+ 与 VC++2015-2022 运行库)。
④ 难度系数:★★★☆☆(中等——以规划、配置、兼容性核查为主,少量代码改动)。
⑤ 其它阅读说明:升级前务必对应用源码(PBL)与数据库(全量备份)各做一份离线备份;建议先在隔离测试环境完整演练一遍再上生产;本文给出的 T-SQL 改写示例需结合你库内实际对象核对,不要照抄表名。
一、升级目标与范围界定
先把"升级"的边界说清楚,避免把简单迁移做成重构。
| 层次 | 现状 | 目标 | 是否必须改代码 | | 客户端运行库 | PB9 VM(pbvm90.dll 等) | PB12.5 VM(pbvm125.dll 等) | 否(重编译即可) | | 字符集 | PB9 是 ANSI(单字节/本地代码页) | PB12.5 是 Unicode UTF-16 | 是,最易踩坑 | | 数据库接口 | PB9 用 MSS Microsoft SQL Server 原生驱动 | PB12.5 用 MSOLEDBSQL / SNC / ODBC | 是,驱动必须换 | | 数据库引擎 | SQL Server 2008(compat 100) | SQL Server 2022(compat 160) | 视对象而定 | | 部署操作系统 | 老 Windows | Windows 10/11、Server 2016+ | 视 OCX/打印等而定 |
核心结论:客户端(PB)最大的风险是字符集(ANSI→Unicode);数据库(MSSQL)最大的风险是废弃 T-SQL 语法 + TLS 连接安全;而两端的交叉点——PB 用老驱动连不上新库——是最容易卡住上线的环节。
二、推荐升级顺序
有两种典型路线,推荐先升数据库、再升客户端,理由是 SQL Server 对老客户端向后兼容更好,可以先用 PB9 连新库做一轮验证。
推荐路线(先库后客户端,双栈并行):
- 阶段 0 备份与盘点:PBL 全量备份 + 数据库全量备份 + 记录现有连接配置(DBMS、DBParm、DSN、登录账号)。
- 阶段 1 升 SQL Server:在新服务器/新实例安装 SQL2022,用"备份-还原"把 2008 库迁过去(还原后兼容级别保持 100)。先让 PB9 + 老 MSS 驱动连上 2022 验证(见 4.4、5.1 的 TLS 注意,老驱动可能需关闭强制加密或用旧协议,仅测试期)。
- 阶段 2 升 PowerBuilder:开发机装 PB12.5,打开 PBL 触发格式升级,全量重新编译,处理 Unicode 与外部函数告警;把数据库连接改为 MSOLEDBSQL(见第五章)。
- 阶段 3 联调:PB12.5 + MSOLEDBSQL 连 SQL2022(compat 100 先跑),回归测试。
- 阶段 4 渐进提升兼容级别:业务稳定后,把库 compat 从 100 → 110 → 120 → 130 → 140 → 150 → 160 逐级提升,每级观察性能与报错(见 4.5)。
不推荐"先升 PB 再升库":PB12.5 的 MSOLEDBSQL/SNC 驱动直连 SQL2008 虽可行,但 SQL2008 已 EOL、无安全补丁,且后续仍要再切一次库,等于两次动荡。
三、PowerBuilder 9 → 12.5 注意事项
3.1 Unicode 是第一道坎(最重要)
PB10 起内核从 ANSI 切换为 Unicode(UTF-16)。代码不用改语法,但语义变了,凡涉及"字节"的逻辑都要复查。
- 字符串函数计数单位变了:Len()、Mid()、Pos()、Left()、Right() 现在按字符计,不再按字节。
- 老代码 Mid(ls_s, 1, 2) 在双字节(中文)场景下结果不同;需要"按字节"的旧逻辑改用 MidA()/LenA()/PosA()/LeftA()/RightA() 系列(A = ANSI/字节语义)。
- Asc()/Char():Asc() 现返回 Unicode 码点;与 Byte() 配合处理单字节时需重新审视。
- Blob 与字符串互转:Blob(ls)、String(lb) 现在是 UTF-16 编码;与外部系统(文件、Socket、COM)交换二进制/文本时,务必显式用 FromUTF8()/ToUTF8() 或 BlobMid 等做编码对齐。
- 外部函数(Declare External Function)调用 Windows API:
- PB12.5 的 MessageBox 实际映射 MessageBoxW(宽字符版);传 string 参数时 PB 自动按宽字符封送。
- 显式声明 API 时要选对 A/W 变体,结构体里含 string 字段的,字段宽度按宽字符(每个字符 2 字节)对齐,否则内存错位。
- 文件 / 注册表 / INI:FileOpen/FileRead、RegistryGet/RegistrySet、ProfileString/SetProfileString 的编码行为随 Unicode 改变,旧 INI 含中文时会乱码,需统一转 UTF-8 或改用注册表/配置表。
3.2 数据库接口变更(MSS → MSOLEDBSQL)
- PB9 的 MSS Microsoft SQL Server 原生驱动在 PB10+ 已被移除。PB12.5 不再有 MSS 接口。
- 改用以下三者之一(推荐 MSOLEDBSQL,可直连 SQL2022):
- MSOLEDBSQL(Microsoft OLE DB Driver for SQL Server,配 18.x/19.x 驱动,支持 2022)
- SNC SQL Native Client (OLE DB)(配 SQLNCLI11,官方支持到 2019,连 2022 不保证)
- ODBC(配 "ODBC Driver 17/18 for SQL Server")
- DBParm 写法随之改变(见第五章完整示例)。
3.3 PBL / PBD 格式与重编译
- 用 PB12.5 打开 PB9 的 PBL 时,库格式会被就地升级,建议先备份再打开。
- 必须全量重新编译(Full Build),不能只增量编译;编译期会暴露 Unicode、废弃属性等问题。
- PB12.5 Classic 仅 32 位,不能用 64 位 OCX/ActiveX;若老系统依赖 64 位组件需另寻方案(或保留 32 位运行)。
- Pcode 与机器码(Machine Code)两种生成方式仍可选;机器码 EXE 仍需随附 PB 运行库。
3.4 废弃与移除的功能
- EAServer / Jaguar / CORBA:PB12.5 已大幅弱化/移除,相关连接代码要改写。
- PowerDynamo、PowerSite:已不再随 PB 发布。
- Web DataWindow / Web Forms(PBNI + ASP.NET):能力受限且依赖特定 IIS/.NET 版本,旧 Web 方案需重新评估。
- 部分老数据库接口、老 OCX 容器:需在 Win10/11 上重新注册验证。
3.5 PFC 与第三方类库
- PFC(PowerBuilder Foundation Class)必须换成与 PB12.5 匹配的版本;直接沿用 PB9 的 PFC PBL 编译会报错。
- 所有 PBNI 扩展(.pbx)必须用 PB12.5 重新编译;PB9 编译的 PBNI 不可混用。
- 自研用户对象、服务(n_cst_* 等)逐库打开、编译、跑一遍。
3.6 运行库与部署清单
- 重发布运行库从 pbvm90*.dll 换成 pbvm125*.dll(含 pbdwe125.dll 数据窗口引擎、pbodb125.dll/pbsyc125.dll 等),以及数据库接口 DLL(见 5.4)。
- 用 PowerBuilder Runtime Packager 生成部署包,避免漏带 DLL。
3.7 语言行为细节
- 日期/时间/小数格式化:String(d, 'yyyy-mm-dd') 等格式串行为基本一致,但区域设置(Locale)在 Unicode 下解析更严格,旧代码里 Date('2026.08.25') 这类非标准写法可能失败,建议统一格式串。
- 字符串比较/排序:Unicode 下按码点比较,与老 ANSI 本地代码页排序结果可能不同(影响 ORDER BY 之外的 PB 内排序逻辑)。
- 隐式类型转换:integer(ls_text) 等转换在异常输入下报错更"硬",建议加 IsNumber() 判断。
四、SQL Server 2008 → 2022 注意事项
4.1 兼容性与升级路径
- 好消息:SQL Server 2022 支持的兼容级别包含 100(即 SQL2008 的级别),所以把 2008 的备份还原到 2022 后,兼容级别保持 100 不变,应用可原样运行。
- 升级方式三选一:
- 备份-还原(最常用):2008 备份 → 2022 还原,compat 保持 100。
- 日志传送 / 镜像(仅过渡):2008 主库 + 2022 辅助,验证后切换(注意 2008 需 SP3+/R2 SP2+)。
- Side-by-Side:新旧实例并存,应用切流。
- 逐级提升兼容级别是安全做法:100 → 110 → 120 → 130 → 140 → 150 → 160,每升一级做回归与性能比对。
- -- 查看当前兼容级别
- SELECT name, compatibility_level FROM sys.databases WHERE name = 'YourDB';
- -- 逐级提升(每级之间做回归测试)
- ALTER DATABASE YourDB SET COMPATIBILITY_LEVEL = 110;
- -- ... 稳定后继续 120 / 130 / 140 / 150 / 160
- ALTER DATABASE YourDB SET COMPATIBILITY_LEVEL = 160;
复制代码
4.2 已移除 / 废弃的 T-SQL 语法(必须改)
这些是上线前必须全库扫描并改写的硬伤,否则在新库直接报错:
| 旧写法(2008 可用) | 问题 | 新写法(2022) | | SELECT a.*, b.* FROM a, b WHERE a.id *= b.id | *=/=* 外连接语法已移除 | FROM a LEFT JOIN b ON a.id = b.id | | TEXT / NTEXT / IMAGE 类型列 | 已废弃 | varchar(max) / nvarchar(max) / varbinary(max) | | BACKUP LOG db WITH NO_LOG / TRUNCATE_ONLY | 已移除 | 切到 SIMPLE 恢复模式或定期 BACKUP LOG | | COMPUTE / COMPUTE BY | 已移除 | GROUP BY ... WITH ROLLUP/CUBE 或窗口函数 | | sp_addlogin / sp_grantlogin / sp_dboption | 已废弃 | CREATE LOGIN / ALTER DATABASE | | RAISERROR 50001 'msg' 旧形式 | 建议改 | THROW 50001, 'msg', 1 | | SELECT DISTINCT * | 不允许 | 显式列名 | | SET FMTONLY ON | 已弃用/移除 | sys.sp_describe_first_result_set 或 WITH RESULT SETS | | fn_get_sql(@handle) | 已移除 | sys.dm_exec_sql_text(@handle) | | sys.sysprocesses / sys.syslockinfo | 已废弃 | sys.dm_exec_requests / sys.dm_exec_sessions / sys.dm_tran_locks |
扫描建议:对存储过程、函数、触发器、视图做 sys.sql_modules 全文本检索上述关键字;PB 端 Embedded SQL 里若写了 *= 也要改。
4.3 数据类型与排序规则
- datetime → datetime2:datetime 精度约 3.33ms、datetime2 精度 100ns。老表可暂不动,新表建议用 datetime2;注意应用层对"毫秒精度"的依赖。
- 排序规则(Collation)差异:2008 常见 SQL_Latin1_General_CP1_CI_AS,2022 默认 Latin1_General_CP1_CI_AS(或中文环境 Chinese_PRC_CI_AS)。还原时排序规则随库保留,但若新建库/重建设计,需显式指定,避免 Cannot resolve the collation conflict 报错。
- 中文环境务必保证数据库、临时库、连接三处排序规则一致或显式 COLLATE。
4.4 连接安全与 TLS(与第五章强相关)
- SQL Server 2022 默认要求 TLS 1.2+,老客户端(PB9 的 MSS 驱动、老 SQLNCLI)往往不支持,会连接失败。
- 加密选项:Encrypt、TrustServerCertificate、Force Encryption(服务端)。测试期可 Encrypt=Yes;TrustServerCertificate=Yes 放宽证书校验,生产应配正式证书。
- 认证模式:保留混合模式(SQL 账号 + Windows),PB 程序跨机连库一般走 SQL 账号。
4.5 性能与查询优化器
- SQL2014 起引入新基数估计器(New CE),2022 默认启用,执行计划可能和 2008 差异巨大,个别语句会变慢。
- 回退手段:ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON;(按库)或用查询提示 OPTION (USE HINT('FORCE_LEGACY_CARDINALITY_ESTIMATION'))。
- Query Store 是 2022 的利器:开启后可对比升级前后计划、强制好计划。
- 升级后务必 UPDATE STATISTICS 全库,并重建/重组索引。
4.6 维护对象迁移
- SQL Agent 作业、维护计划、SSIS 包:需重新部署到新实例;作业步骤里的 xp_cmdshell、CMDEXEC 要重新授权(默认禁用)。
- 登录 / 用户 / 权限:用 sp_help_revlogin 或 CREATE LOGIN 迁移登录;还原库后常见孤立用户,用 ALTER USER ... WITH LOGIN = ... 重新映射。
- CLR 程序集:SQL2022 默认 CLR strict security,旧 SAFE/EXTERNAL_ACCESS 程序集需签名并建非对称密钥/登录,否则无法注册。
4.7 其它弃用项
- 全局跟踪标志、部分 DMV 旧名、旧式 BACKUP ... WITH PASSWORD 等均已弃用,迁移脚本里注意清理。
五、PB 与 MSSQL 的对接层(最关键,最易卡上线)
5.1 为什么老驱动连不上 2022
PB9 的 MSS 驱动底层依赖老 SQL Server 客户端协议,不支持 TLS 1.2;而 SQL2022 默认强制加密连接。两者握手直接失败。因此"PB12.5 + 正确驱动"是连 2022 的前提。
5.2 PB12.5 连接 2022 的三种方式
- MSOLEDBSQL(推荐):客户端安装 Microsoft OLE DB Driver for SQL Server 18.x/19.x,PB 用 MSOLEDBSQL 接口(DLL:PBMSOLEDBSQL.dll),官方明确支持 2012–2022。
- ODBC Driver 17/18:建系统 DSN 或直接连字符串,PB 用 ODBC 接口。
- SNC(SQLNCLI11):仅官方支持到 2019,连 2022 不保证,不推荐作为最终方案。
5.3 DBParm 关键参数与完整示例
下面是 PB12.5 用 MSOLEDBSQL 连 SQL2022 的推荐写法(含测试连接与 MessageBox 输出,符合本论坛代码规范):
- // 演示:PB12.5 通过 MSOLEDBSQL 接口连接 SQL Server 2022
- // 前置:客户端已安装 "Microsoft OLE DB Driver for SQL Server 19.x"
- // 输入变量(前段声明并赋值,逐行说明用途)
- string ls_server // 数据库服务器地址,本机实例用 "localhost\SQLEXPRESS"
- string ls_db // 目标数据库名,例如 "DemoDB"
- string ls_user // SQL 登录账号(混合模式下使用),例如 "pbapp"
- string ls_pwd // 登录密码
- string ls_connstr // 拼接好的连接字符串
- ls_server = "localhost\\SQLEXPRESS" // 注意 PowerScript 字符串里反斜杠需转义为 \\
- ls_db = "DemoDB"
- ls_user = "pbapp"
- ls_pwd = "YourStrongPwd123!"
- // 使用 MSOLEDBSQL 接口;Encrypt 强制 TLS,测试期 TrustServerCertificate=Yes 放宽证书校验
- ls_connstr = "Provider=MSOLEDBSQL;" + &
- "Server=" + ls_server + ";" + &
- "Database=" + ls_db + ";" + &
- "User ID=" + ls_user + ";" + &
- "Password=" + ls_pwd + ";" + &
- "Encrypt=Yes;TrustServerCertificate=Yes;"
- SQLCA.DBMS = "MSOLEDBSQL" // PB12.5 数据库接口类型
- SQLCA.LogId = ls_user // 登录账号
- SQLCA.LogPass = ls_pwd // 登录密码
- SQLCA.AutoCommit = False // 用事务提交,不用自动提交
- SQLCA.DBParm = "ConnectString='" + ls_connstr + "',TrimSpaces=1,StaticBind=0"
- CONNECT USING SQLCA; // 执行连接
- IF SQLCA.SQLCode = 0 THEN
- MessageBox("连接成功", "已连上 SQL Server 2022:" + ls_db)
- ELSE
- MessageBox("连接失败", "错误码=" + String(SQLCA.SQLCode) + "~n" + SQLCA.SQLErrText)
- END IF
复制代码参数说明:TrimSpaces=1 去除 char 字段尾部空格;StaticBind=0 让列绑定按结果集动态绑定(推荐);CommitOnDisconnect 默认 False 即断开不自动提交;Windows 集成登录可去掉 LogId/LogPass,在 ConnectString 加 Integrated Security=SSPI。
5.4 部署时必带的 DLL
- 数据库接口:PBMSOLEDBSQL.dll(用 MSOLEDBSQL 时)、pbsnc.dll(用 SNC 时)、pbodb125.dll(ODBC 时需要)。
- 运行库:pbvm125.dll、pbdwe125.dll、pbsyc125.dll、libjcc.dll、libjtml.dll 等(由 Runtime Packager 打包)。
- 客户端机器必须先装 Microsoft OLE DB Driver for SQL Server(或对应 ODBC 驱动),否则 PB 接口 DLL 加载后连不上。
六、代码与数据库对象迁移清单(可勾选)
PowerBuilder 侧
- [ ] 全量 PBL 备份,用 PB12.5 打开触发格式升级
- [ ] 全量重新编译,修复 Unicode/废弃属性告警
- [ ] 扫描所有 Declare External Function,核对 A/W 变体与结构体宽度
- [ ] 字符串"按字节"逻辑改用 MidA/LenA/PosA
- [ ] Blob/文件/注册表/INI 的中文编码统一为 UTF-8 处理
- [ ] 数据库连接由 MSS 改为 MSOLEDBSQL,更新 DBParm
- [ ] PFC 与所有 PBNI 扩展用 PB12.5 重新编译
- [ ] OCX/ActiveX 在 Win10/11 上重新注册验证(注意 32 位限制)
- [ ] 用 Runtime Packager 重新生成部署包
SQL Server 侧
- [ ] 数据库全量备份(含日志)
- [ ] 备份-还原到 2022,确认 compat 保持 100 先跑
- [ ] 全库 sys.sql_modules 扫描并改写 4.2 表格中的废弃语法
- [ ] TEXT/NTEXT/IMAGE 列改为 max 类型
- [ ] 排序规则核对(库/连接一致,必要时 COLLATE)
- [ ] 迁移登录账号,修复孤立用户
- [ ] 重部署 SQL Agent 作业 / SSIS / 维护计划
- [ ] CLR 程序集按 strict security 重新签名注册
- [ ] 开启 Query Store,UPDATE STATISTICS,重建索引
- [ ] 逐级提升 compat 级别并回归
七、测试、回滚与上线策略
- 隔离测试环境:新库 + PB12.5 先在独立机演练,禁止直接动生产。
- 回归测试重点:中文乱码、日期/小数格式、外部函数调用、打印/报表、批量导入导出、长事务。
- 回滚方案:
- 数据库:保留 2008 原库不删,出问题切回 PB9 + 老库(老环境先别卸载)。
- 应用:PB9 编译的旧 EXE 留一份,可立即回退。
- 灰度上线:先非核心模块/少量用户试用,再全面切换。
- 兼容级别是安全网:联调先用 compat 100 保证"能跑",稳定后再逐级升 160 解锁新特性。
八、典型坑与排错(FAQ)
| 现象 | 根因 | 处理 | | PB 连 2022 报"找不到网络路径/握手失败" | 老 MSS/SNC 不支持 TLS1.2 | 换 MSOLEDBSQL + 装 OLE DB Driver 19,设 Encrypt=Yes;TrustServerCertificate=Yes | | 中文显示乱码 / 截断 | ANSI→Unicode 计数单位变化 | Mid/Len 改 MidA/LenA;外部接口显式 UTF-8 编码 | | 语句在新库直接报错(语法) | *= 外连接、TEXT 类型、COMPUTE 等已移除 | 按 4.2 表格改写 | | 升级后某些查询突然变慢 | 新基数估计器计划变化 | 开 Query Store 对比;必要时 LEGACY_CARDINALITY_ESTIMATION=ON | | 报 collation conflict | 库与临时表/连接排序规则不一致 | 统一排序规则或显式 COLLATE | | 还原后应用登录失败 | 孤立用户 | ALTER USER ... WITH LOGIN = ... 重新映射 | | PBNI 扩展加载报错 | PB9 编译的 .pbx 不兼容 | 用 PB12.5 重新编译 PBNI | | OCX 注册失败/崩溃 | PB12.5 仅 32 位,老 64 位 OCX 不兼容 | 换 32 位 OCX 或替代组件 |
九、时间规划建议(里程碑)
| 阶段 | 主要工作 | 建议工期(参考) | | P0 盘点备份 | 源码/库备份、连接配置记录、对象清单 | 1–2 天 | | P1 升数据库 | 装 2022、还原、compat100 先跑、扫描废弃语法 | 3–5 天 | | P2 升客户端 | 装 PB12.5、重编译、Unicode 改造、换驱动 | 1–2 周(视代码量) | | P3 联调回归 | PB12.5+MSOLEDBSQL 连 2022、功能/性能测试 | 1–2 周 | | P4 渐进提升 | compat 逐级升 160、Query Store 调优 | 1 周(含观察期) | | P5 灰度上线 | 非核心先用、回滚预案就位 | 1–2 周 |
工期仅供参考;老系统代码量越大、外部函数/OCX 越多,P2 越久。关键是每个阶段都有可回退点,不要一口吃成胖子。
一句话总结:PB9→12.5 盯住 Unicode,MSSQL2008→2022 盯住 废弃 T-SQL + TLS,两端交叉点盯住 MSOLEDBSQL 驱动;先用兼容级别 100 保"能跑",再逐级升 160 解锁新特性,全程保留回退能力。 |