如何从查询中检索列数据类型?

时间:2015-08-31 18:46:19

标签: .net vb.net oledb database-schema

我想检索从(任何)SQL查询返回的列的数据类型(使用OLE DB)。我的假设是,在GetSchemaTable对象上调用OleDbDataReader方法会在ProviderType列中提供此信息。要将此数字转换为实际名称,我在DataTypes模式表中搜索该值。

我的代码如下:

Private Sub Test()

    Dim cs = "Provider=SQLOLEDB;Initial Catalog=TestDb;Data Source=127.0.0.1;User ID=XXX;Password=XXX"
    Dim schemaTable As DataTable
    Dim dataTypesTable As DataTable

    Using conn = New OleDbConnection(cs)

        conn.Open()

        Using command = conn.CreateCommand()
            command.CommandText = "SELECT *, 42 AS Foo, CURRENT_TIMESTAMP AS Bar FROM DataItem"

            Using reader = command.ExecuteReader(CommandBehavior.SchemaOnly And CommandBehavior.KeyInfo)
                schemaTable = reader.GetSchemaTable()
            End Using
        End Using
        dataTypesTable = conn.GetSchema("DataTypes")

    End Using

    For Each row As DataRow In schemaTable.Rows

        Dim name = row.Field(Of String)("ColumnName")
        Dim providerType = row.Field(Of Int32)("ProviderType")

        Dim types = dataTypesTable.Rows.OfType(Of DataRow).
                    Where(Function(r) r.Field(Of Int32)("ProviderDbType") = providerType).
                    Select(Function(r) r.Field(Of String)("TypeName"))

        Console.WriteLine($"Column: {name}, Provider type: {providerType}, Types: {String.Join(", ", types)}")
    Next
End Sub

DataItem表的定义如下(SQL Server 2012):

CREATE TABLE [dbo].[DataItem](
    [Id] [uniqueidentifier] NOT NULL,
    [NvarcharValue] [nvarchar](50) NOT NULL,
    [NvarcharNullValue] [nvarchar](50) NULL,
    [DateValue] [date] NOT NULL,
    [DateNullValue] [date] NULL,
    [TimeValue] [time](7) NOT NULL,
    [TimeNullValue] [time](7) NULL,
    [DatetimeValue] [datetime] NOT NULL,
    [DatetimeNullValue] [datetime] NULL,
    [SmallintValue] [smallint] NOT NULL,
    [SmallintNullValue] [smallint] NULL,
    [IntValue] [int] NOT NULL,
    [IntNullValue] [int] NULL,
    [BigintValue] [bigint] NOT NULL,
    [BigintNullValue] [bigint] NULL,
    [RealValue] [real] NOT NULL,
    [RealNullValue] [real] NULL,
    [FloatValue] [float] NOT NULL,
    [FloatNullValue] [float] NULL,
    [NumericValue] [numeric](10, 3) NOT NULL,
    [NumericNullValue] [numeric](10, 3) NULL,
    [BitValue] [bit] NOT NULL,
    [BitNullValue] [bit] NULL,
    [ImageValue] [image] NOT NULL,
    [ImageNullValue] [image] NULL,
    [VarbinaryValue] [varbinary](50) NOT NULL,
    [VarbinaryNullValue] [varbinary](50) NULL,
    [GeometryNullValue] [geometry] NULL,
    [GeographyNullValue] [geography] NULL,
    [NvarcharMaxNullValue] [nvarchar](max) NULL,
 CONSTRAINT [PK_DataItem] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

这是实际输出:

Column: Id, Provider type: 72, Types: uniqueidentifier Column: NvarcharValue, Provider type: 202, Types: date, time, datetime2, datetimeoffset, nvarchar Column: NvarcharNullValue, Provider type: 202, Types: date, time, datetime2, datetimeoffset, nvarchar Column: DateValue, Provider type: 202, Types: date, time, datetime2, datetimeoffset, nvarchar Column: DateNullValue, Provider type: 202, Types: date, time, datetime2, datetimeoffset, nvarchar Column: TimeValue, Provider type: 202, Types: date, time, datetime2, datetimeoffset, nvarchar Column: TimeNullValue, Provider type: 202, Types: date, time, datetime2, datetimeoffset, nvarchar Column: DatetimeValue, Provider type: 135, Types: smalldatetime, datetime Column: DatetimeNullValue, Provider type: 135, Types: smalldatetime, datetime Column: SmallintValue, Provider type: 2, Types: smallint Column: SmallintNullValue, Provider type: 2, Types: smallint Column: IntValue, Provider type: 3, Types: int Column: IntNullValue, Provider type: 3, Types: int Column: BigintValue, Provider type: 20, Types: bigint Column: BigintNullValue, Provider type: 20, Types: bigint Column: RealValue, Provider type: 4, Types: real Column: RealNullValue, Provider type: 4, Types: real Column: FloatValue, Provider type: 5, Types: float Column: FloatNullValue, Provider type: 5, Types: float Column: NumericValue, Provider type: 131, Types: decimal, numeric Column: NumericNullValue, Provider type: 131, Types: decimal, numeric Column: BitValue, Provider type: 11, Types: bit Column: BitNullValue, Provider type: 11, Types: bit Column: ImageValue, Provider type: 205, Types: image Column: ImageNullValue, Provider type: 205, Types: image Column: VarbinaryValue, Provider type: 204, Types: varbinary Column: VarbinaryNullValue, Provider type: 204, Types: varbinary Column: GeometryNullValue, Provider type: 205, Types: image Column: GeographyNullValue, Provider type: 205, Types: image Column: NvarcharMaxNullValue, Provider type: 203, Types: ntext, xml Column: Foo, Provider type: 3, Types: int Column: Bar, Provider type: 135, Types: smalldatetime, datetime

我的问题是有多个提供程序类型具有相同的ProviderDbType值,我无法选择正确的提供程序类型。例如,对于列NvarcharValue,我希望得到nvarchar类型。但datetimedatetime2datetimeoffsetnvarchar具有相同的值202。我做错了什么?

修改 为了澄清,我想得到所有返回值的类型,而不仅仅是一个特定表的列。因此,我不能简单地在SQL Server上查询INFORMATION_SCHEMA(或sys.columnssys.types。我相应地修改了代码,使其更加明显。

1 个答案:

答案 0 :(得分:0)

我希望这会有所帮助。  下面是一个示例脚本,用于标识SQL SERVER

中特定数据库中的所有列数据类型和其他信息
SELECT
OBJECT_NAME(c.OBJECT_ID) TableName
,c.name AS ColumnName
,SCHEMA_NAME(t.schema_id) AS SchemaName
,t.name AS TypeName
,t.is_user_defined
,t.is_assembly_type
,c.max_length
,c.PRECISION
,c.scale
FROM sys.columns AS c
JOIN sys.types AS t ON c.user_type_id=t.user_type_id
ORDER BY c.OBJECT_ID;