如何从Ado.Net中的VARCHAR检索Bytes[]

本文关键字:检索 Bytes VARCHAR 中的 Ado Net | 更新日期: 2023-09-27 18:26:00

我需要将SQL表中存储为varchar的一些数据检索到c#中的字节[]。

SQL服务器正在运行MS SQL server 2005。有问题的表有一列定义为varchar(3900),非null。该列通常由c++代码直接写入不同的POD结构来填充。基本上将指向结构的指针传递给更新表的c++sql代码。不同的c++程序读取和写入该表,并共享描述这些POD结构的相同标头。POD结构的类型由表中的另一列指示。让我们称之为DataType不能更改表的定义方式(作为列)。这将需要对目前运作的系统进行巨大变革。

如何在C中获取varchar到bytes[]的完整内容(3900字节)#我的目标是使用ADO.net从这个表中获取行。读取此列和DataType列。根据DataType,按照c++POD结构的骨架构建一个Object。

然后如何从我的C#对象向varchar写回表(3900)。

我读过这个问题,但ADO.net似乎将此列视为字符串,然后截断内容。我似乎无法获得varchar列的"原始"内容。

知道吗?

编辑:

In c++写入列的数据被声明为char[3901]。使用memcopy将完整的POD结构"写入"在其上。在使用ADO存储在表中之前:它首先使用MultiByteToWideChar转换为WideCharString然后是一个B字符串BSTR,它又被放入一个VARIANT中,最后由ADO用来更新表。

如何从Ado.Net中的VARCHAR检索Bytes[]

给定一个表

create table foobar
(
  id        int           not null primary key ,
  some_text varchar(2000) not null ,
)

检索some_text作为八位字节:

select id = id ,
       some_octets = convert(varbinary(2000),some_text)
from foobar

插入和更新:

declare @id          int
declare @some_octets varbinary(2000)
insert foobar ( id , some_text ) values ( @id , convert(varchar(2000),@some_octets) )
update foobar set @some_text = convert(varchar(2000),@some_octets)
where id = @id

当然,我应该给出强制性的"您应该使用二进制数据类型来存储二进制数据…",但我相信您知道这一点,并且无论出于什么原因,您都会使用varchar数据类型。

也就是说,这里有一段非常基本的ADO.NET代码,用于读取/写入二进制数据。

代码假设下表存在

CREATE TABLE BinTest
(
   BinData varchar(3000) NOT NULL
)

下面的代码将向表中插入一个二进制数据数组,并将其读回。对于限制为varchar大小的数组,这应该不需要使用更高级的方法来读取二进制数据。

using System;
using System.Data.SqlClient;
class Program
{
  static void Main(string[] args)
  {
    byte[] bytes = new byte[]{0,1,2,3,4,65,66,4,3,2,1,0};
    using(var con = new SqlConnection(@"<your connection string here>"))
    {
      con.Open();
      var cmd = con.CreateCommand();
      // Insert binary data into varchar
      cmd.CommandText = "insert into BinTest (BinData) values (cast(@BinData as varbinary))"; 
      cmd.Parameters.AddWithValue("BinData", bytes);
      cmd.ExecuteNonQuery();
      // Read binary data from varchar
      cmd.Parameters.Clear();
      cmd.CommandText = "select cast(BinData as varbinary) from BinTest";
      using (var rdr = cmd.ExecuteReader())
      {
        while (rdr.Read())
        {
          if (!rdr.IsDBNull(0))
          {
            var data = rdr.GetSqlBinary(0);
            Console.WriteLine(BitConverter.ToString(data.Value));
          }
        }
      }
    }
  }
}

根据数据的编码,您可以使用LINQ和BitConverter来处理从字符串到字符数组到字节数组的转换,然后再转换回来,如本示例片段所示。

string TestValue = "1234567890";
byte[] Result = TestValue.ToCharArray().SelectMany(item => BitConverter.GetBytes(item)).ToArray<byte>();
string BackToTestValue = new string(Result.Select((item, index) => BitConverter.ToChar(Result, Math.Min(index, Result.Length - 2))).Where((item, index) => index % 2 == 0).ToArray<char>());

当然,您将使用从数据库中读取的值,而不是这里显示的固定测试字符串。我想你已经从其他答案中看到了这一点。