C# 从SQL Server数据库获取二进制列

C# 从SQL Server数据库获取二进制列,c#,sql,sql-server,C#,Sql,Sql Server,我需要使用C#从SQL Server数据库导入列 当我使用SQL Server Enterprise时,它显示为,当我在SQL Server上运行查询时,它返回正确的二进制值 但是,当我尝试使用C#编码时,就像这样: 当我放入reader.GetSqlBinary(0)时,我只得到许多SqlBinarys作为输出 当我查看SQL Server查询分析器时,当我尝试相同的命令时,它会得到0x0000..类型的代码 我应该在读者之后写些什么。或者是否有其他方法从数据库中获取此数据?您正在获取一个字节

我需要使用C#从SQL Server数据库导入列

当我使用SQL Server Enterprise时,它显示为
,当我在SQL Server上运行查询时,它返回正确的二进制值

但是,当我尝试使用C#编码时,就像这样:

当我放入
reader.GetSqlBinary(0)时
,我只得到许多
SqlBinary
s作为输出

当我查看SQL Server查询分析器时,当我尝试相同的命令时,它会得到
0x0000..
类型的代码


我应该在读者之后写些什么。或者是否有其他方法从数据库中获取此数据?

您正在获取一个字节数组,因此请使用:

byte[] bytes = (byte[])reader[0];

从那里处理它们取决于字节代表的内容

您应该从
SqlDataReader
indexer()访问数据

所以看起来是这样的:

//..
Console.WriteLine((byte[])reader["bnry"]); 
//..
SqlConnection conn = new SqlConnection("Server=portable;Database=data;Integrated Security=true;");
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT bnry FROM RawData", conn);
SqlDataReader reader = cmd.ExecuteReader();

while(reader.Read())
{
    var valueAsArray = (byte[])reader["bnry"];

    //as there are different encodings possible, you need to find encoding what works for you
    var valueAsStringDefault = System.Text.Encoding.Default.GetString(valueAsArray);
    Console.WriteLine(valueAsStringDefault);

    //...or...
    var valueAsStringUTF8 = System.Text.Encoding.UTF8.GetString(valueAsArray);
    Console.WriteLine(valueAsStringUTF8);

    //...or...
    var valueAsStringUTF7 = System.Text.Encoding.UTF7.GetString(valueAsArray);
    Console.WriteLine(valueAsStringUTF7);

    //...or any other encoding. Most of them you can find in System.Text.Encoding namespace...
}

reader.Close();
conn.Close();
更新:

我想我终于明白你的问题出在哪里了。我们在这方面的立场不同。我会尽量简单

对于start,您需要了解计算机中的所有信息都以一组字节的形式存储在内存中。直接处理内存中的字节非常麻烦,因此引入了不同的数据类型(
int
string
Image
,等等),以简化程序员的工作。NET中的大多数对象仍然可以通过某种方式转换为字节数组的内部表示形式。在此转换过程中,您会丢失有关字节数组包含内容的信息—它可以很容易地是
Image
string
甚至
int
数组要从二进制表示返回,您需要知道字节数组包含什么。

在您的示例中,您试图直接写出字节数组。由于输出总是需要是文本,字节数组需要以某种方式转换为
string
。这是通过在字节数组上调用
.ToString()
函数来完成的。不幸的是,复杂对象的
.ToString()
的默认实现只返回类型名称。这就是所有那些
System.Byte[]
SqlBinary
行的来源

为了克服这个问题,在显示结果之前,您需要将字节数组转换为必要的类型。在您的示例中,字节数组似乎包含一些文本信息,因此我想您需要将字节数组转换为
字符串。要做到这一点,您需要知道文本的编码(字符串
如何存储在内存中)

基本上,您的代码应该如下所示:

//..
Console.WriteLine((byte[])reader["bnry"]); 
//..
SqlConnection conn = new SqlConnection("Server=portable;Database=data;Integrated Security=true;");
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT bnry FROM RawData", conn);
SqlDataReader reader = cmd.ExecuteReader();

while(reader.Read())
{
    var valueAsArray = (byte[])reader["bnry"];

    //as there are different encodings possible, you need to find encoding what works for you
    var valueAsStringDefault = System.Text.Encoding.Default.GetString(valueAsArray);
    Console.WriteLine(valueAsStringDefault);

    //...or...
    var valueAsStringUTF8 = System.Text.Encoding.UTF8.GetString(valueAsArray);
    Console.WriteLine(valueAsStringUTF8);

    //...or...
    var valueAsStringUTF7 = System.Text.Encoding.UTF7.GetString(valueAsArray);
    Console.WriteLine(valueAsStringUTF7);

    //...or any other encoding. Most of them you can find in System.Text.Encoding namespace...
}

reader.Close();
conn.Close();

更好的方法是使用流,以便在完成时正确地处理流(可能通过套接字连接)。所以我会用

给这张桌子

create table dbo.bin_test
(
  c1 binary(8)    not null ,
  c2 binary(8)        null ,
  c3 varbinary(8) not null ,
  c4 varbinary(8)     null ,
)
insert dbo.bin_test values ( 0x1234     , null       , 0x1234     , null       )
insert dbo.bin_test values ( 0x012345678 , 0x12345678 , 0x12345678 , 0x12345678 )
此代码(如果要使用
SQLBinary

但如前所述,简单地这样做可能更干净:

byte[] octets = reader[0] as byte[] ;
if ( octets == null )
{
  Console.WriteLine( "{null}");
}
else
{
  Console.WriteLine( "length={0:##0}, {{ {1} }}" , octets.Length , string.Join( " , " , octets.Select(x => string.Format("0x{0:X2}",x)))) ;
}

然后得到相同的结果。

那么使用查询分析器和企业(大概是管理器)是否意味着您使用的是SQL Server 2000?这将是非常相关的信息(因为那个版本太古老了,今天SQL Server中的大多数方法都不能使用这样的版本),它给了我一个错误的说法“System.Data.SqlClient.SqlDataReader”不包含“Items”的定义,并且找不到接受“System.Data.SqlClient.SqlDataReader”类型的第一个参数的扩展方法“Items”“有一个打字错误-应该说是
Items
,而不是
Items
。修正了。抱歉,误读了文档。它不是属性,而是
SqlDataReader
本身的索引器。再次编辑。这一次我自己试过了,效果很好。当我像你写的那样放的时候,没有错误,但是它给了我
System.byte[]
s,这是我最初遇到的问题..当我做
byte[]bytes=(byte[])读卡器[0];Console.WriteLine(bytes)
它仍然给了我很多
System.Byte[]
s…对,这就是应该发生的事情。字节应该是什么?如果它是图像,您可以使用
MemoryStream
对象和
image.FromMemoryStream()
方法将其转换为图像,或者通过
File.writealBytes(byteArray)
将其保存到磁盘。它们都会给我
与“string.Join”(string,string[])的最佳重载方法匹配的错误'具有一些无效参数
参数“2”:无法从'System.Collections.Generic.IEnumerable'转换为'string[]”
您使用的CLR(.Net runtime)的哪个版本
String.Join()
获得了使用.Net 4.0的
IEnumerable
的重载。如果您使用的是.Net 2.0/3.5,则需要将
.ToArray()
附加到
八位字节。选择(…)
row 0, col 0: length=8, { 0x12 , 0x34 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }
row 0, col 1: {null}
row 0, col 2: length=2, { 0x12 , 0x34 }
row 0, col 3: {null}

row 1, col 0: length=8, { 0x00 , 0x12 , 0x34 , 0x56 , 0x78 , 0x00 , 0x00 , 0x00 }
row 1, col 1: length=8, { 0x12 , 0x34 , 0x56 , 0x78 , 0x00 , 0x00 , 0x00 , 0x00 }
row 1, col 2: length=4, { 0x12 , 0x34 , 0x56 , 0x78 }
row 1, col 3: length=4, { 0x12 , 0x34 , 0x56 , 0x78 }
byte[] octets = reader[0] as byte[] ;
if ( octets == null )
{
  Console.WriteLine( "{null}");
}
else
{
  Console.WriteLine( "length={0:##0}, {{ {1} }}" , octets.Length , string.Join( " , " , octets.Select(x => string.Format("0x{0:X2}",x)))) ;
}