sys.dm_exec_describe_first_result_set 返回错误的数据类型

Muf*_*lix 3 t-sql system-tables sql-server-2016

我有两个与链接服务器连接的 SQL Server 2016。当我sys.dm_exec_describe_first_result_set从远程服务器查询时,它返回列表的数字数据类型而不是十进制。

第一个查询(从远程服务器执行)

select * from sys.dm_exec_describe_first_result_set (N'select top 1 * from LinkedServerFoo.DatabaseFoo.dbo.TargetTable', NULL, 0) [source]
Run Code Online (Sandbox Code Playgroud)

第二个查询(从sql server执行)

select * from sys.dm_exec_describe_first_result_set (N'select top 1 * from DatabaseFoo.dbo.TargetTable', NULL, 0) [source]
Run Code Online (Sandbox Code Playgroud)

结果

在此输入图像描述

这对我来说是一个问题,因为我根据这些查询的输出来比较数据类型。

知道可能出现什么问题吗?为什么会这样以及如何解决?

  • smalldatetimewhere sys 表错误返回也存在同样的问题datetime

Dan*_*man 5

系统类型 106 和 108 分别是十进制和数字。这些类型名称是同义词,可以互换使用:

SELECT system_type_id, name
FROM sys.types
WHERE system_type_id IN(106, 108);

+----------------+---------+
| system_type_id |  name   |
+----------------+---------+
|            106 | decimal |
|            108 | numeric |
+----------------+---------+
Run Code Online (Sandbox Code Playgroud)

本地查询返回用于创建列的原始 DDL 指定的类型名称。然而,链接服务器查询返回链接服务器驱动程序返回的类型名称。在我的测试中,名称numeric与列实际上是否定义为numericor无关decimal

怎么解决呢?

一种解决方法是在 TVFSELECT列表中使用显式列名称*,以便您可以将类型名称转换为一致的名称。例如:

SELECT
      is_hidden 
    , column_ordinal    
    , REPLACE(name, N'decimal', N'numeric') AS name
    , is_nullable   
    , system_type_id
    , REPLACE(system_type_name, N'decimal', N'numeric') AS system_type_name
    , max_length    
    , precision 
    , scale 
    , collation_name    
    , user_type_id  
    , user_type_database    
    , user_type_schema  
    , user_type_name    
    , assembly_qualified_type_name  
    , xml_collection_id 
    , xml_collection_database   
    , xml_collection_schema 
    , xml_collection_name   
    , is_xml_document   
    , is_case_sensitive 
    , is_fixed_length_clr_type  
    , source_server 
    , source_database   
    , source_schema 
    , source_table  
    , source_column 
    , is_identity_column    
    , is_part_of_unique_key 
    , is_updateable 
    , is_computed_column    
    , is_sparse_column_set  
    , ordinal_in_order_by_list  
    , order_by_is_descending    
    , order_by_list_length  
FROM sys.dm_exec_describe_first_result_set(N'select top 1 * from DatabaseFoo.dbo.TargetTable;', DEFAULT, DEFAULT) AS source;
Run Code Online (Sandbox Code Playgroud)