sql-server - 在 VB.NET 中检索 UDT 表结构

标签 sql-server vb.net stored-procedures sql-server-2012 user-defined-types

在搜索我的答案时,我看到了这个问题: ADO.NET Retrieve UDT Columns from SQL Server 2012?但仍未得到答复。简而言之,这是我的问题,但上下文如下。

我有一个 SQL Server 2012 存储过程,它采用两个表值参数 (TVP),我想从 VB.NET(现在是 3.5,但我不喜欢这个)调用它们。我已经使用 SqlCommandBuilder.DeriveParameters 来确定我的存储过程的参数:

cmd1 = New SqlCommand()
cmd1.Connection = oCn2 ' assume properly connected to database
cmd1.CommandText = "uspInsertTestData"
cmd1.CommandType = CommandType.StoredProcedure
SqlCommandBuilder.DeriveParameters(cmd1)

我的存储过程如下所示:

ALTER Procedure [dbo].[uspInsertTestData]
        @Processor varchar(20),
        @TRes [dbo].[TestResultsType] READONLY,
        @EXSetup ExtraTestSetupType READONLY,
        @ErrNum int OUTPUT,
        @ErrString varchar(300) OUTPUT
AS
BEGIN
-- ... stuff
END

我的 UDT 表类型如下所示:

CREATE TYPE [dbo].[TestResultsType] AS TABLE(
    [ResultValue] [sql_variant] NULL,
    [ResultInfo] [varchar](50) NULL,
    [ResultUnits] [char](20) NULL,
    [PassedTest] [varchar](15) NULL,
    [TestName] [varchar](30) NULL,
    [TestTypeName] [varchar](50) NULL,
    [MinLimit] [float] NULL,
    [MaxLimit] [float] NULL,
    [UUTTemperature] [float] NULL)

CREATE TYPE [dbo].[ExtraTestSetupType] AS TABLE(
    [FieldName] [varchar](50) NULL,
    [FieldValue] [varchar](50) NULL,
    [Units] [char](20) NULL)

DeriveParameters() 的调用按预期填充了 cmd1.Parameters,我也可以识别两种 UDT 表类型 - Parameters.TypeName 表示它们实际上是 UDT 表类型 - 此代码:

Debug.Print("parameter [" & p.ParameterName & "]: SqlDbType=[" & _
      p.SqlDbType().ToString() & "]: TypeName=[" & p.TypeName() & "])

产量:

parameter [@Processor]: SqlDbType=[VarChar]: TypeName=[]
parameter [@TRes]: SqlDbType=[Structured]: TypeName=[LMUTesterData.dbo.TestResultsType]
parameter [@EXSetup]: SqlDbType=[Structured]: TypeName=[LMUTesterData.dbo.ExtraTestSetupType]
parameter [@ErrNum]: SqlDbType=[Int]: TypeName=[]
parameter [@ErrString]: SqlDbType=[VarChar]: TypeName=[]

综上所述,问题是:

1:有没有办法DERIVE UDT表类型的列?我研究过的所有示例都将使用 DataTable.Columns.Add() 将 COLUMNS 添加到数据表,然后再将它们作为参数传递给存储过程。理想情况下,我想使用 Parameter.TypeName 值来检索 UDT 的结构。

2:如果对 1 的回答是“否”,当我使用 DataTable.Columns.Add() 构建我的 UDT 结构时,它是否必须与UDT 本身?给定上面 TestResultstype 的 UDT 定义,是否可以:

DataTable dataTable = new DataTable("TestResultsType"); 
dataTable.Columns.Add("ResultUnits", GetType(string)); 
dataTable.Columns.Add("ResultInfo", GetType(string)); 
dataTable.Columns.Add("ResultValue", GetType(float)); 
dataTable.Columns.Add("TestTypeName", GetType(string)); 
dataTable.Columns.Add("UUTTemperature", GetType(float)); 
dataTable.Columns.Add("MinLimit", GetType(float)); 
dataTable.Columns.Add("MaxLimit", GetType(float)); 

3:唯一的方法是实现为 CLR(公共(public)语言运行时)程序集吗?

最佳答案

Private Function DataTableForServerType(ByVal Connection As SqlConnection, ByVal ServerTypeName As String) As DataTable

    Dim SanitisedQualifiedTypeName As String

    Using cmd = New SqlCommand()
        cmd.Connection = Connection
        cmd.CommandType = CommandType.Text
        cmd.CommandText = "select top (1) quotename(schema_name([schema_id]), '[') + N'.' + quotename([name], '[') from [sys].[types] where [name] = parsename(@type_name,1) and [schema_id] = isnull(schema_id(parsename(@type_name,2)), [schema_id]) and [is_table_type] = 1;"
        cmd.Parameters.Add("@type_name", SqlDbType.NVarChar, 128).Value = ServerTypeName

        SanitisedQualifiedTypeName = CType(cmd.ExecuteScalar(), String)

        If String.IsNullOrEmpty(SanitisedQualifiedTypeName) Then
            Throw New Exception(String.Format("Table type '{0}' does not exist or you don't have permission.", ServerTypeName))
        End If
    End Using


    Using ada = New SqlDataAdapter("declare @t " & SanitisedQualifiedTypeName & "; select * from @t;", Connection)
        Dim res As New DataTable

        ada.Fill(res)

        Return res
    End Using

End Function

关于sql-server - 在 VB.NET 中检索 UDT 表结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26608765/

相关文章:

sql-server - 如何从#temp 表生成插入数据脚本?

sql-server - 使用 Restore-SqlDatabase cmdlet 时无法绑定(bind) RelocateFile

vb.net 大于十进制的数据类型

vba - 在 Access 中使用 SQL Server 存储过程的输出参数

mysql - 过程中的 SQL 1064

sql - 需要有关 SQL 查询的帮助(自连接)

sql-server - 加入链接服务器表时提高查询性能

vb.net - 如何将事件处理程序添加到 VB.NET 中的局部变量

vb.net - 使用关键字作为标识符无效 --> ReadOnly

mysql - 插入查询在存储过程中不起作用