【问题标题】:SQL Binary Conversion vs .Net Binary ConversionSQL 二进制转换与 .Net 二进制转换
【发布时间】:2011-09-14 21:49:29
【问题描述】:

我在 MS SQL 服务器中有一张这样的表:

CREATE TABLE Setting
(
   ID int NOT NULL,
   Value varbinary(MAX) NOT NULL
)

Value列中的信息可以格式化为字符串、布尔值、整数、小数等。例如:

INSERT INTO Setting (Value) VALUES (CONVERT(VARBINARY(MAX), 5.4))

要选择数据,我可以在将数据返回到 .Net 之前转换值,但我更希望我的选择过程返回二进制数据,然后在 .Net 中执行正确的类型转换。这样,我就可以同时选择以不同格式存储的多个设置。

我不知道如何将返回的二进制数据转换为正确的类型(尤其是整数和十进制)。数据库以字节数组(byte[])的形式返回二进制数据,但是从字节数组到整数或小数的转换似乎不太支持。

我最初的想法是使用 System.Convert,但它不支持字节数组。

我的第二个解决方案是使用 System.IO.BinaryWriter 和 System.IO.BinaryReader。这个方法给了我这个错误:“无法读取超出流的末尾。”

例子:

cmd.CommandText = "SELECT CONVERT(VARBINARY(MAX), 2.3)";
byte[] bytes = (byte[])ExecuteSelect(cmd).Rows[0][0];
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.BinaryWriter br = new System.IO.BinaryWriter(ms);
br.Write(bytes);
System.IO.BinaryReader br2 = new System.IO.BinaryReader(ms);
decimal d = br2.ReadDecimal();

我的第三次尝试是使用 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter,但这会返回错误消息:“在解析完成之前遇到流结束。”

例子:

cmd.CommandText = "SELECT CONVERT(VARBINARY(MAX), 2.3)";
byte[] bytes = (byte[])ExecuteSelect(cmd).Rows[0][0];
System.IO.MemoryStream ms = new System.IO.MemoryStream();
ms.Write(bytes, 0, bytes.Length);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
decimal d = (decimal)bf.Deserialize(ms);

我目前的解决方案是将值的类型传递给存储过程,并使用 case 语句将值转换为字符串。

如果我可以在不连接到数据库的情况下从 .Net 访问 MS SQL 的转换函数,我的首选解决方案是。

我不想使用自制函数进行转换。我需要一个可靠的解决方案。

我的环境是 .Net 2008、C# 或 VB

任何想法都将不胜感激。

【问题讨论】:

  • 是否可以选择额外的列来指定类型?否则,您是否控制进入表格的数据和读取它的代码?
  • 哇!你为什么要转换任何东西?将其作为 blob 放入(带有 byte[] 值的参数);将其作为 blob 取回(GetValue() 返回 byte[])。没有附加条件...
  • 还有;在我看来(基于大量的序列化工作)你不应该在这里使用 BinaryFormatter;它是特定于平台的,版本不兼容(使其变得脆弱且难以保证您以后可以读取数据),并且有边缘情况的习惯,例如导致失败的事件。严重地;我不认为这是个好主意。二进制序列化很好,只是没有 BinaryFormatter

标签: .net sql-server-2008 type-conversion binary-data


【解决方案1】:

您的第一次尝试很接近,有BitConverter.ToDouble 或您想将其转换为的任何内容。

您的第二次尝试也很接近,您只是在阅读之前没有倒带(这是多么疯狂的迂回方式......)。

至于您的第三次尝试,您还没有吸取有关 I/O 的教训。

编辑:我不相信你会从那个东西中得到小数。您应该仔细检查您的类型...

【讨论】:

  • 我尝试使用 BitConverter,但它似乎不起作用。在数据库中,我将 2.3 转换为二进制,然后 BitConvert.ToDouble 将返回 4.88141923657287E-313。这对于整数也是类似的。我尝试为两种流方法设置 Position = 0,但我得到相同的错误消息。
  • 尝试在您的select 中为2.3 提供一个实际类型。
  • 感谢您的快速回复。我可以执行 SELECT CONVERT(DECIMAL(6,3), CONVERT(VARBINARY(MAX), 2.3)) ,这将返回 2.3 作为小数,但随后我正在数据库中进行转换。我更愿意返回二进制数据并将其转换为 .Net 中的小数,但似乎 .Net 和 MSSQL 对二进制数据的编码方式不同。
猜你喜欢
  • 2021-07-29
  • 2014-02-10
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 2023-04-11
  • 1970-01-01
  • 2011-09-04
  • 2016-10-02
相关资源
最近更新 更多