【问题标题】:Inserting Bytearray into SQL through stored procedure called in C#通过在 C# 中调用的存储过程将 Bytearray 插入 SQL
【发布时间】:2012-01-27 09:12:04
【问题描述】:

首先我已经尝试了所有方法,但不明白为什么它不能正确更新我的 varbinary 字段。

在 1728 个字节中,只有字节数组中的最后一个字节被保存到字段中...

我按如下方式生成我的字节数组:

public static byte[] StringToByteArray(String hex)
{
    int NumberChars = hex.Length;
    byte[] bytes = new byte[NumberChars / 2];
    for (int i = 0; i < NumberChars; i += 2)
        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
    return bytes;
}

我也尝试过以下一种:

public static byte[] ParseHex(string hex)
{
    int offset = hex.StartsWith("0x") ? 2 : 0;
    if ((hex.Length % 2) != 0)
    {
        throw new ArgumentException("Invalid length: " + hex.Length);
    }
    byte[] ret = new byte[(hex.Length - offset) / 2];

    for (int i = 0; i < ret.Length; i++)
    {
        ret[i] = (byte)((ParseNybble(hex[offset]) << 4)
                         | ParseNybble(hex[offset + 1]));
        offset += 2;
    }
    return ret;
}

static int ParseNybble(char c)
{
    if (c >= '0' && c <= '9')
    {
        return c - '0';
    }
    if (c >= 'A' && c <= 'F')
    {
        return c - 'A' + 10;
    }
    if (c >= 'a' && c <= 'f')
    {
        return c - 'a' + 10;
    }
    throw new ArgumentException("Invalid hex digit: " + c);
}

我保存数据的c#代码是这样的:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DB_Conn"].ConnectionString))
{
  byte[] to_store = StringToByteArray(inventory);

  //State the Stored Proc and add Values to 'cmd' to pass to the Stored Proc
  SqlCommand cmd = new SqlCommand("_USP_store", conn);
  cmd.CommandType = CommandType.StoredProcedure;
  cmd.Parameters.AddWithValue("@A", TB_A.Text);
  cmd.Parameters.Add("@B", SqlDbType.VarBinary, 1728).Value = to_store;

  try
  {
    // Open Connection and execute Stored Proc
    conn.Open();
    cmd.ExecuteNonQuery();
    C2_Wipe_Message.Text = "Storing success";
    C2_Wipe_Message.ForeColor = Color.FromArgb(0, 0, 255, 0);

  }
  catch
  {
    C2_Wipe_Message.Text = "An error occured..";
    C2_Wipe_Message.ForeColor = Color.FromArgb(0, 255, 0, 0);
  }
  finally
  {
    if (conn.State == System.Data.ConnectionState.Open)
    {
      //Close connection IF open
      conn.Close();
    }
  }
}

我已将其作为字符串发送,我已将其作为纯二进制发送,我已将其作为十六进制字节数组发送,等等。

我的假设是在sql中使用while循环来存储它,但这并不能解释为什么总是保存最后一个字节而不是字节数组的第一个字节,请赐教,因为这令人气愤..

*SQL SP

@A varchar(10),
@B varbinary(1728)

    AS  

UPDATE Invenotry
SET A = @B
WHERE (Name = @A)

【问题讨论】:

  • 让我们看看我认为问题所在的 SQL,因为在 SQL 中使用循环对我来说是错误的。
  • 不使用循环,但我会得到 sql 过程
  • [Invenotry].[A]字段的类型是什么?
  • 这是一个 varchar(10) 字段,它包含一个名称。应用程序必须有字段,为简单起见,字段 A 和字段 B,字段 A 保存名称,字段 B 保存人类可读的十六进制字节数组的输出/输入。
  • 根据具有字段 A 和 B 的表查看下面的答案。如果不是这种情况,请发布 Invenotry 的表定义

标签: c# sql stored-procedures bytearray


【解决方案1】:

你的 sql 应该是这样的:

UPDATE Invenotry
SET B = @B
WHERE A = @A

你也可以试试完整版的参数构造函数:

SqlParamter param = new SqlParameter("@B", SqlDbType.VarBinary, 1728, ParameterDirection.Input, 
     // we have these parameters but they are ignored for input types
     false, 0, 0, null, DataRowVersion.Current, 
     // the data
     to_store);

cmd.Parameters.Add(param);

【讨论】:

  • 现在测试它,一个附带的问题,我描述的上述两种方法将使用哪种方法将十六进制字符串转换为字节数组?或者你会使用不同的方法吗?
  • 它似乎不喜欢 WHERE 子句周围的 '(' 和 ')',但是我注意到我最大的问题是给字段一个正确的名称。我现在已经相应地更改了字段名称,并且还为 varbinary 字段分配了适当的大小(它是 1726 而不是 1728 ..)虽然我仍然对您推荐哪种转换为 Byte 数组感兴趣
  • 第一个看起来更简单,但是它不检查起始0x——你希望看到起始0x吗?
  • 我期待任何最适合数据库字段的方法,并且开销最低。
  • 我认为目标是让它们都返回相同的东西——我希望内部库会更快,但最好的方法是测试两者。
猜你喜欢
  • 2012-01-05
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多