使用Sql_Variant时的原始数据类型引用

时间:2017-04-28 09:08:04

标签: sql-server tsql sql-server-2012 sql-variant

我正在创建一个包含SQLVariant数据类型的表。变体列中存储的值可以是字符串整数和/或日期时间。我读到了sqlvariant的缺陷,但由于该列没有被索引,或者在WHERE子句中使用,它似乎是最好的选择。但是,我需要存储一个引用SqlVariant应该从/到的适当数据类型。

在Microsoft .Net(我的应用程序)中,每个SQL data type都有一个基础数值:

enter image description here

我在TSQL中看不到等效系统,所以想知道我在使用它时如何引用每种数据类型。每个TSQL数据类型都有“ID”吗?

此要求的原因是客户端将值作为XML传递给过程,该过程将值保存到表中,例如

<parameters>
    <p ID="1" Value="2017-04-28" Type="?????" /> Perhaps the SqlDbType integer value from above (4), or an equivalient TSQL identifier?
    <p ID="2" Value="123" Type="Integer" />
    <p ID="3" Value="123.456" Type="Double" />
    <p ID="4" Value="Foo Bar" Type="String" />
</parameters>

我应该只使用.Net的SqlDbType值,还是有更好的方法?

更新

想想我可能找到了什么......

SELECT * FROM sys.types

我需要system_type_id这个值吗?

1 个答案:

答案 0 :(得分:2)

您可以创建用户定义的表类型,以将参数数组作为表值参数传递:

SQL代码: CREATE TYPE MyType AS TABLE (ID int, Value Sql_Variant)

CREATE PROCEDURE SP_NAME 
    @Values dbo.MyType READONLY
AS
    --@Values is usual table variable (but readonly) and you can select from it like from tables in database
    INSERT INTO SomeDBTable
    SELECT * 
    FROM @Values V
    WHERE V.ID <= 100500

.NET代码

DataTable dtList = new DataTable();
List<SqlDataRecord> filterList = new List<SqlDataRecord>();
foreach (KeyValuePair<string, object> filter in arrFilterList)
{
    SqlDataRecord record;

    record = new SqlDataRecord(new SqlMetaData[] { new SqlMetaData("ID", SqlDbType.Int),
                                      new SqlMetaData("Value", SqlDbType.Variant) });
    record.SetInt(0, filter.Key);
    record.SetValue(1, filter.Value);
    filterList.Add(record);
}
SqlCommand oCommand = new SqlCommand("SP_NAME", connection);
oCommand.CommandType = CommandType.StoredProcedure;
oCommand.Parameters.AddWithValue("@Values", filterList.Count > 0 ? filterList : null);
oCommand.Parameters["@Values"].SqlDbType = SqlDbType.Structured;
oCommand.Parameters["@Values"].TypeName = "dbo.MyType";