SQLCMD 版本输出对于 Informix 的不同 RHEL 版本是不同的

SQLCMD version output is different for different RHEL versions for Informix

我们正在使用 "sqlcmd" 来处理 Informix DB。我们的脚本使用 "info columns for " 命令提取列和 prepare/run 查询。

但是,迁移到 RHEL7 后,最新版本的 SQLCMD 将具有不同的输出模式。

Eg: RHEL6
$ echo "info columns for <table>" | dbaccess 2>&1 | head
1|<column 1>|258|4|0
2|<column 2>|7|4|0
3|<column 3>|0|2|0
... etc

RHEL7
$ echo "info columns for <table>" | dbaccess 2>&1 | head
colno              1
colname            <column 1>
coltype            258
collength          4
extended_id        0

colno              2
colname            <column 2>
coltype            7
collength          4

版本如下:

RHEL 6
$ dbaccess -V
dbaccess: SQLCMD Version 87.00 (2010-10-21)
IBM Informix CSDK Version 3.50, IBM Informix-ESQL Version 3.50.FC7
GNU Readline 6.0
(C) Copyright Jonathan Leffler 1987-2010
Licenced under GNU General Public Licence Version 2

RHEL 7
$ dbaccess -V
dbaccess: SQLCMD Version 90.02 (2016-07-28)
IBM Informix CSDK Version 4.10, IBM Informix-ESQL Version 4.10.FC2DE
GNU Readline 6.2
(C) Copyright Jonathan Leffler 1987-2016
Licenced under GNU General Public Licence Version 2

我们是否有使 sqlcmd 向后兼容的解决方案?它是一些标志驱动的吗?我们必须支持 RHEL6 和 RHEL7。

我只是有点偏见——我写了 SQLCMD(1).

您在 90.02 版中显示的输出反映了添加 'block' 模式输出格式以更好地模拟 DB-Access,并且当您使用 sqlcmd 通过姓名 dbaccess.

所以,是的,行为发生了变化。 SQLCMD 90.02 现在比 87.00 更能模拟 DB-Access。

这个问题也与 RHEL 6 和 RHEL 7 没有直接关系;而是与SQLCMD的版本有关。

我不确定是否有一种简单的方法可以恢复到原来的行为。使用 dbaccess -F select stores - 不会覆盖现代版本中的默认值; 运行 format select; 作为命令。这是一个轻微的麻烦,但并不完全令人惊讶。我愿意在命令行参数处理的其余部分之前设置名称 dbaccess 隐含的格式模式,以便命令行选项覆盖隐含的格式。 运行 SQLCMD 通过 dbaccess -C 将其放回 sqlcmd 模式,但这意味着它不像 DB-Access 那样解释数据库名称和文件名参数。 (例如,在 dbaccess 模式下,如果您没有像 DB-Access 那样首先添加扩展名,它会向文件名添加 .sql 扩展名;sqlcmd 不会这样做。)

'best' 解决方案是修改脚本以直接使用 SQLCMD。但是,这意味着改变的不仅仅是命令名称;您必须在数据库名称前添加 -d 并为文件名添加 .sql 后缀。

可以更改 SQLCMD 以添加环境变量,例如 SQLCMD_FORMAT,如果未在命令行上明确覆盖,该变量就会生效。将其设置为 select 将恢复旧的输出格式。另一种可能性是添加对 .sqlcmdrc 文件的支持,其中包含要在启动时执行的命令。不过,我不确定是否要添加它。

我建议通过电子邮件与我联系(请参阅 SQLCMD 文档或我的 SO 配置文件)以讨论从这里发生的事情 — 请在主题行中包含 SQLCMD。

顺便说一句,作为短期解决方法,没有什么可以阻止您在 RHEL 7 上使用 SQLCMD 87.00。或者,您可能会发现需要编辑 jlss.h 以删除或更新memmem() 的声明 — 它在 87.00 代码中,因为当时我不知道该函数在某些平台上可用 — 它既不是 C11 也不是 POSIX 2017 的一部分。 从 return 类型中删除 const。当我使用 GCC 7.3.0 在 macOS 10.13.4 (High Sierra) 上编译 87.00 时,我收到了一些其他编译警告,但它们无害(无论它们多么不受欢迎)。但是 2010 年的代码不一定能在更现代的系统上干净地编译。


(1) link 可能需要向 IIUG 注册。这是免费的,不需要大量的电子邮件——我估计通常每周少于一封——除非你选择订阅一些讨论频道。