在SQL视图中使用ALL_SPARSE_COLUMNS列集查询稀疏列失效问题
问题场景
现有一张支持动态新增稀疏列的数据表,初始建表语句如下:
CREATE TABLE [dbo].[my_table]( [id] [BIGINT] NOT NULL, [column_set] XML COLUMN_SET FOR ALL_SPARSE_COLUMNS)
运行阶段会动态执行SQL新增稀疏列,语句格式如下:
ALTER TABLE my_table ADD my_sparse_column ... SPARSE
基于该表创建视图的初始语句如下:
CREATE VIEW [dbo].[v_my_view] AS SELECT v.* FROM my_table v
异常表现
通过上述视图查询新增的稀疏列数据时无法正常返回结果,示例查询语句:
SELECT my_sparse_column FROM v_my_view
执行查询会抛出列不存在的报错,但完全相同的查询语句直接在基表my_table上执行可正常运行。
核心原因:SQL Server普通视图在创建时会固化绑定当时的基表元数据,即使定义时使用SELECT *语法,后续给基表新增的列(含动态新增的稀疏列)不会自动同步到视图结构中,因此查询时无法识别新增列名。
可行解决方案
- 新增列后自动刷新视图元数据
每次执行ALTER TABLE新增稀疏列完成后,调用系统内置存储过程刷新视图的元数据绑定即可,不需要修改视图定义:
可以将该存储过程的调用逻辑直接写入新增稀疏列的脚本中,加列完成后自动执行,无需人工干预。EXEC sp_refreshview [dbo].[v_my_view] - 通过列集直接查询稀疏列
调整视图定义,直接返回稀疏列对应的XML列集,不做列展开,后续新增的所有稀疏列都会自动包含在XML返回结果中,无需刷新视图:
查询时通过XML方法提取需要的稀疏列值即可,示例:ALTER VIEW [dbo].[v_my_view] AS SELECT id, column_set FROM my_tableSELECT id, column_set.value('(/my_sparse_column)[1]', 'NVARCHAR(100)') AS my_sparse_column -- 替换为实际字段类型 FROM v_my_view - 用内联表值函数替代普通视图
如果使用SQL Server 2016及以上版本,可改用内联表值函数实现视图的等价能力,调用时会自动读取基表最新元数据,缺点是调用语法和普通视图有差异。
内容的提问来源于stack exchange,提问作者Sheinar
相关产品推荐
相关产品推荐

