You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ODBC查询SQL Server列缺失:sp_columns与INFORMATION_SCHEMA.columns不匹配

问题背景

Linux环境下的Oracle 12.1通过dg4odbc及Linux版MS-SQLServer ODBC驱动连接Windows上的SQL Server,使用select * from schema.table@dblink查询SQL Server数据基本可行,但遇到以下异常:

  • 执行select * from INFORMATION_SCHEMA.columns where table_name = 'X'返回全部242列,但select * from X仅返回约64列,且所有domain_catalog列非空的字段均缺失,缺失无规律(存在带/不带domain_catalog值的bigint列)。
  • 为排除Oracle接口问题,使用Linux上的Microsoft sqlcmd(版本11和18,搭配对应ODBC驱动)测试:执行exec sp_columns BUV_BUCHUNGSVARIANTE仅返回2行,而select * from BUV_BUCHUNGSVARIANTE显示全部10列(仅涉及微软工具及ODBC驱动,无Oracle参与)。

问题1:为何select *会缺失domain_catalog非空的列?

这是因为ODBC驱动(尤其是旧版本的SQL Server ODBC驱动)在处理**用户自定义数据类型(UDT)**的元数据时存在缺陷。domain_catalog非空的列本质是基于用户自定义数据类型创建的,驱动在解析这类列的元数据时出错,导致Oracle dg4odbc或sqlcmd的sp_columns无法识别这些列;但直接执行select *时SQL Server本身能正常返回数据,只是驱动层过滤掉了这些列的元数据,最终表现为查询结果缺失列。

问题2:列级别上的domain_catalog含义是什么?

在SQL Server的INFORMATION_SCHEMA.columns中,domain_catalog表示用户自定义数据类型(UDT)所在的数据库名称。如果列使用的是系统内置数据类型(如int、varchar),该字段为空;只有当列使用用户自行创建的自定义数据类型时,该字段才会填充为该UDT所属的数据库名。

问题3:开发者为何会设计带/不带domain_catalog项的列?

  • 使用系统内置数据类型(domain_catalog为空):满足常规业务需求,内置类型兼容性好、性能稳定,无需额外维护,适合大多数通用场景。
  • 使用用户自定义数据类型(domain_catalog非空):主要为了统一数据格式和约束,比如多个表需要使用相同的编号规则(如固定长度的员工ID),可以创建自定义类型统一管理,避免重复设置约束;同时也能提升代码可读性,用有业务含义的类型名替代抽象的内置类型。

问题4:连接SQL Server的账号需具备哪些权限才能访问表的所有列?

要访问表的所有列,账号需要具备以下权限:

  • 目标表的SELECT权限:这是读取表数据的基础权限。
  • 用户自定义数据类型(UDT)的VIEW DEFINITION权限:因为domain_catalog非空的列依赖UDT,若无该权限,驱动无法获取UDT的元数据,会导致这类列被过滤。
  • 若涉及跨数据库的UDT,还需要具备UDT所在数据库的CONNECT权限,以及对该UDT的VIEW DEFINITION权限。

内容的提问来源于stack exchange,提问作者dipr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:55:12