我在SQL Server 2012中有一个表值参数定义为:
CREATE TYPE [dbo].[TVP] AS TABLE (
[Id] [int] NOT NULL,
[FieldName] [nvarchar](100) NOT NULL,
[Value] [sql_variant] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
我在C#中使用代码看起来大致如下所示:
var mdItems = new DataTable();
mdItems.Columns.Add("Id", typeof(int));
mdItems.Columns.Add("FieldName", typeof(string));
mdItems.Columns.Add("Value", typeof(object));
mdItems.Rows.Add(new object[] {2, "blah", "value"}); //'value' is usually a string
SqlCommand sqlCommand = conn.CreateCommand();
sqlCommand.CommandText = "[WriteFieldValues]";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("@FieldValues", mdItems);
sqlCommand.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
然后,我在ExecuteNonQuery
调用SQL Server时收到以下错误:
不支持"值"列的类型.类型是'对象'
我发现有人在3年前遇到了同样的问题,当时它被认定为已知的Microsoft bug.但是,该错误的链接已被破坏.有谁知道是否有关于错误状态或潜在解决方法的最新信息?就目前而言,这个错误确实会破坏sql_variant
字段的价值.
c# sql-server sql-variant table-valued-parameters sql-server-2012
我目前有一个数据库表设置如下(EAV - 业务原因是有效的):
这允许我将混合值作为键/值对添加到我的数据库中.例如:
1 | 'Some Text' | 'Hello World'
2 | 'Some Number' | '123456'
etc.
Run Code Online (Sandbox Code Playgroud)
在我的C#代码,我用ADO.Net使用reader.GetString(2);
检索值作为一个字符串,然后让我的代码的其他地方将其转换为所需,例如... Int32.ParseInt(myObj.Value);
.我正在考虑通过将value列更改为sql_variant
数据类型来增强我的表,但我不知道这会带来什么好处?基本上,它有什么优势将我的价值列是sql_variant
VS varchar(1000)
?
为了更清楚,我在某处读到sql_variant以nvarchar(4000)的形式返回给调用的客户端(ouch)!但是,在返回它之前,我不能把它转换成它的类型吗?显然,我的代码必须进行调整,以将值存储为对象而不是字符串值.我想,sql_variant
在我目前的情况下使用与其他类型相比有哪些优点/缺点?哦,值得一提的是我计划存储的所有内容都是值列中的日期时间,字符串和数字类型(int,decimal等); 我不计划存储和blob或图像等.
似乎最近已在Entity Framework Core中添加了支持,.NET Core 2.1 (preview)
以允许SQL_VARIANT
列的映射(https://github.com/aspnet/EntityFrameworkCore/issues/7043)。
看来要执行此操作的HasConversion()
方法是使用新方法(https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions)。
因此,为了映射我的SQL_VARIANT
列并将基础数据类型视为VARCHAR
任意长度的a(我现在只在乎读取它),我可以执行以下操作(此处的Value
属性是object
模型中的类型):
entity.Property(e => e.Value).HasConversion(v => v.ToString(),
v => v.ToString());
Run Code Online (Sandbox Code Playgroud)
如果SQL_VARIANT
的基础数据类型为VARCHAR
任意长度,则此方法有效。
但是,作为a SQL_VARIANT
,列可以包含其他类型的数据,例如DATETIME
值。
为简单起见,我只规定DateTime
和string
这里,但在理论上我可能要支持任何可以被存储在一个必要的映射数据类型SQL_VARIANT
,如果可能的列。
如何确定在运行时要映射到的两种类型(string
和DateTime
)中的哪一种?有没有办法做到这一点?
关系数据库管理系统通常使用 SQL 的特定变体。例如,SQL Server 使用 Transact-SQL 又名 T-SQL。
我知道 MariaDB 基于 MySQL(RDBMS),而 MySQL 使用的 SQL 变体显然本身也称为 MySQL(根据这个问题)。我应该假设 MariaDB 也使用 MySQL 语言吗?
我尝试了几次 Google 搜索,但一无所获。由于 RDBMS 和语言之间的混淆,这很棘手。大多数结果只是将 MariaDB 与 MySQL(RDBMS)进行比较。
我有一个表有一个SQL_Variant类型的列和一些其他类型的类,如int,bigint,...当我将此表添加到edmx文件时,它添加所有列,但SQL_Variant类型列.是否有错误或我必须做一些事情来添加该列?
我有一种情况,两个相同类型的对象有不同类型的父母.以下伪代码最好地解释了这种情况:
TypeA a1, a2;
TypeB b;
TypeC c;
a1.Parent = b;
a2.Parent = c;
Run Code Online (Sandbox Code Playgroud)
更复杂的是,TypeB和TypeC可能具有不同类型的主键,例如,以下断言可能为真:
Assert(b.Id is string && c.Id is int);
Run Code Online (Sandbox Code Playgroud)
我的问题是在SQL Server中定义这种父子关系的最佳方法是什么?我能想到的唯一解决方案是定义TypeA表有两列 - ParentId和ParentType,其中:
但是,当我基于sql_variant定义用户数据类型时,它将字段大小指定为固定的8016字节,这似乎很多.
必须有一个更好的方法.任何人?谢谢.
sql-variant ×6
c# ×3
sql ×2
sql-server ×2
.net-core ×1
mariadb ×1
mysql ×1
performance ×1
rdbms ×1
varchar ×1